写点什么

讨论:Java 编程风格的改变

  • 2009-08-17
  • 本文字数:2209 字

    阅读完需:约 7 分钟

最近 Stephan Schmidt 在博客中发表了题为《下一代 Java 编程风格》的文章,阐述了他眼中 Java 编程风格的改变,以及未来的走向:

许多公司和开发人员正在从 Java 转向其他编程语言:Ruby、Python、Grrovy、Erlang 或 Scala 等等。不过你可能做不到这一点。即便如此,你也可以改变你的编程风格,获取这些新语言的优势。事实上,在过去的 15 年中,Java 编程风格也已经有明显变化了。

Stephan 在文章中提出了以下几点:

  1. 尽可能地标注 final:让所有东西不可变,把变量标为 final 可以阻止改变它的值。很多时候,重新为变量赋值会引入 bug,你应该使用新的变量。除此之外,final 可以提高代码的可读性。我针对这个话题还写过一篇文章:《 Java 中所有变量都应该是 final 的
  2. 没有 setter:许多 Java 程序员会自然而然地为类中所有的字段加上 setter。思考一下,真的每个字段都需要修改吗?更好的方法是创建包含改变后状态的新对象。此外,也试着去除 getter,我们应该遵循“ Tell, don’t ask ”的思想。
  3. 避免使用循环来操作 List:从函数式编程那里获得的经验,循环并不是进行集合操作最好方法。例如,我们可以使用 Google Collections 提供的过滤功能。 ```

Predicate canDrinkBeer = new Predicate() {
public boolean apply(HasAge hasAge) {
return hasAge.isOlderThan( 16 );
}
};

List beerDrinkers = filter(persons, canDrinkBeer);

复制代码
4. ** 使用单行代码:**Java 是一门繁杂(noisy)的语言,我们应该编写更精确的代码。尝试将代码写为一行。例如: ```
public int add(int a, int b) { return a + b; }
  1. 使用大量接口:领域驱动设计已经大行其道,一个应该拆分为多种“角色”,即实现多种接口,提高复用程度。方法应该面向“角色”,而不是面向特定的类。我在《不要在 Java 中使用 String 》一文中讨论了更多这方面的内容。
  2. 使用 Erlang 风格的并发:Java 的并发特性(如 lock 和 synchronized)过于低端,难以使用。Erlang 风格的并发是一种更好的做法。Java 平台上已经有了 Akka Actorom 。此外,也可以使用 java.util.concurrent 中的 Join/Fork 和数据结构进行编程。
  3. 使用 Fluent Interface:Fluent Interface 可以使代码更短,更容易编写。Google Collections 中的 MapMaker 是个不错的示例: ```

ConcurrentMap graphs = new MapMaker()
.concurrencyLevel(32)
.softKeys()
.weakValues()
.expiration(30, TimeUnit.MINUTES)
.makeComputingMap(
new Function() {
public Graph apply(Key key) {
return createExpensiveGraph(key);
}
});

复制代码
8. ** 避免在 DTO 中创建 gettersetter:** 如果你拥有简单的 DTO(Data Transfer Object),不要耗费精力去编写 gettersetter,直接使用公开的字段吧。不过在你无法完全控制代码的使用情况时,还是小心为上。

这篇文章发表之后,有许多人发表了不同的看法。其中 Cedric Otaku 发表了文章《下一代 Java 与现在差不多》予以回应,其中反对了 Stephan 提出的大部分观点。

  • 尽可能 final:太多 final 会降低代码的可读性,它无法代码额外的好处。我已经不记得上次因为重新给变量赋值而造成错误是什么时候了。值得一提的是,在字段以外的成员上标记 final 违反了 Google 的风格指南。
  • 避免 setter:看上去不错,不过这不现实。有些时候你不愿把所有的参数都通过构造函数传入。此外,如果使用对象池的时候,可变的对象会让编程更为方便。Stephan 不是第一个提出要将访问器(accessor)从 OO 编程中移除的人,不过这个说法很明显不可行
  • 避免循环:Java 并不适合函数式编程风格,所以我认为使用 Predicate 的代码反而难以读懂。我估计大部分的 Java 程序员会同意我的观点,即使他们已经熟悉了闭包风格。
  • 单行代码:这要视情况而定。并引入临时变量把一个表达式拆开可以提高代码可读性,也容易为其设置断点。
  • 使用接口:不错的建议,但也不能过火。过去我也争论过类似的话题,不过引入太多接口会导致细小类型的爆炸,使你高端的类型意图变得模糊。
  • Erlang 风格并行:重申一点,使用 Java 设计以外的编程风格是危险的做法。java.util.concurrent 中包含了非常有用的功能,我遇到过不少基于这些元素的 Java 抽象,它们要优于 Erlang 风格的 actor 架构。
  • Fluent Interface:这个建议比较有趣,它与 Stephan 提出的另一个建议“避免 setter”相违背。Fluent Interface 只是 setter 的另一种形式,不是吗?
  • 使用公有字段:不,千万别这么做。你不会因为加了访问器而后悔,但是我能保证你会因为一时偷懒,使用了公有字段而后悔莫及。

在 Cedric 的文章之后,Stephan 又对他的说法进行了补充:

没有 setter 并不代表你不能修改这个对象,我只是说纯粹的 setter 不是面向对象的思维方式。例如,你觉得 stop() 和 setStop(true) 哪个更好一些?

(针对 Predicate 代码不易读)我认为你的假设有误。循环是“程序化”的代码,而 Predicate 是经过封装的,可以重用的,易于理解的“对象”。这里并没有函数式编程,这里是纯粹的 OO - 我提起 FP 只是因为我从那里“引入”了这个方式。

还有许多人对 Stephon 和 Cedric 的文章发表了评论,例如有人支持 Stephan 的观点,认为 final 的可以更好的表示出代码的意图。甚至有人提出:

更简单的解决方案是使用 Scala :) - 不可变的状态、统一访问原则(字段、属性、方法看上去一样)、单行代码、使用 monads 或函数来替代循环……这些特性都已经在 Scala 中优雅地体现出来了。

您的 Java 编程风格是什么样的,和过去相比有什么改变吗?

2009-08-17 10:276006
用户头像

发布了 157 篇内容, 共 62.3 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

github 这样用,事半功倍

hepingfly【gzh:和平本记】

Java GitHub 搜索 使用技巧

B+树索引优点

一个大红包

3月日更

后台产品导航栏原型设计小教程

lenka

3月日更

Python基础之:Python的数据结构

程序那些事

Python 程序那些事 python数据结构

华为云数据库GaussDB(for openGauss):初次见面,认识一下

华为云开发者联盟

数据库 分布式 华为云 GaussDB(for openGauss) 开源数据库

设计有意义的选择——再谈心流

Justin

心理学 28天写作 游戏设计

手机

ES_her0

28天写作 3月日更

Python 的特殊变量 __name__

HoneyMoose

Go训练营第5周——评论系统架构设计

Glowry

看完了进程同步与互斥机制,我终于彻底理解了 PV 操作

飞天小牛肉

Java 程序员 面试 操作系统

《2020年IT行业项目管理调查报告》重磅发布

禅道项目管理

开源 项目管理 项目 调查报告 互联网行业薪资

产品经理训练营 Week9 学习心得

Mai

GO训练营第8周——分布式缓存与事务

Glowry

GO训练营第9周——网络编程

Glowry

2021 OS 大赛来了,为中国操作系统发展按下加速键

InfoQ写作社区官方

热门活动

超简单的网站暗黑模式,它真的超简单!

HelloGitHub

大前端

容器 & 服务:Kubernetes扩容

程序员架构进阶

Docker 容器 kubernete 28天写作 3月日更

翻译:《实用的Python编程》06_04_More_generators

codists

Python

(28DW-S8-Day27) 销售流程重整

mtfelix

28天写作

JVM - 类加载机制

insight

3月日更

企业大数据实战:Kyuubi 与 Spark ThriftServer 的全面对比分析

网易数帆

大数据 spark Kyuubi Thrift HiveServer2

聊聊 Python 自动化脚本部署服务器全流程(详细)

星安果

Python 自动化 服务器 部署

经典排序算法分析

roseduan

算法 排序算法

产品经理训练营 Week9 作业

Mai

@Component,@Service等注解是如何被解析的?

Java小咖秀

spring 面试 工作 注解 经验

全球币系统开发案例(源码)

系统开发咨询1357O98O718

算法攻关-最长公共子序列_1143

小诚信驿站

刘晓成 小诚信驿站 28天写作 算法攻关 最长公共子序列

Nirvana NA公链 NAC公链的两面观

区块链第一资讯

mybatis实现分页的几种方法

xiezhr

mybatis 分页 mybatis分页

Wireshark 数据包分析学习笔记Day15

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

GO训练营第6、7周——可用性设计

Glowry

讨论:Java编程风格的改变_Java_赵劼_InfoQ精选文章