QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

讨论: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:275697
用户头像

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

关注

评论

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

WorkPlus高端制造行业数字化解决方案—华晨宝马

BeeWorks

开源 即时通讯 IM 案例分享 汽车

Rust从0到1-智能指针-Drop trait

rust smart pointer drop trait

见康乘拼团软件开发|见康乘拼团系统APP开发

多项目同时进行如何做好项目管理?

万事ONES

与微软、IBM同台 斯图飞腾Stratifyd入选G2文本分析Grid报告

测试开发之网络篇-常用命令

禅道项目管理

Linux 命令行

Fil和BTC有什么区别?Filecoin挖矿的行情如何?

IPFS BTC fil fil币

WICC 2021召开在即 清华大学教授将分享AI+网络音视频服务研究

融云 RongCloud

用中国话学this指向(旧知识新讲)

加百利

JavaScript 大前端 this 7月日更

深入理解搜索引擎——初识query理解

药老算法

搜索引擎 中文分词 query理解 query纠错 query分析

pha挖矿/phala挖矿APP系统开发内容

智汇华云|华云数据ArSDN:自主可控的SDN

华云数据

就在今天,浪潮云说第二期来啦

云计算

【Flutter 专题】92 图解 Dart 单线程实现异步处理之 Isolate (一)

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 7月日更

图的应用——关键路径

若尘

数据结构

互斥锁Mutex:鸿蒙轻内核中处理临界资源独占的“法官”

华为云开发者联盟

鸿蒙 OpenHarmony 鸿蒙轻内核 互斥锁Mutex 临界资源

CODING 带你看腾讯新闻 7 日 DevOps 实践

CODING DevOps

DevOps CODING 腾讯新闻

2021 WAIC | EMQ 映云科技:面向云原生的云边协同物联网解决方案

EMQ映云科技

云原生 云端 端边云协同架构 边云协同

毕业季offer怎么拿?收下这份非典型求职面试指南

华为云开发者联盟

面试 职业规划 求职 毕业季 大学生

原来这就是Java IO啊····

华为云开发者联盟

Java 操作系统 进程 IO流 Java IO

面向编程式多云管理服务时代的华为云MCP多云跨云的容器治理与实践

华为云开发者联盟

容器 云原生 华为云 多云 跨云

如何对开发团队的人员进行绩效管理?

万事ONES

研发效能 ONES 绩效管理

FIL矿机多少钱一台 ?FIL挖矿成本是多少?

【LeetCode】主要元素Java题解

Albert

算法 LeetCode 7月日更

pha分币APP系统开发资料

Redisson 分布式锁源码 07:公平锁释放

程序员小航

Java redis 源码 分布式锁 redisson

永续合约交易所搭建,合约平台开发

WorkPlus房地产行业数字化解决方案—富力地产

BeeWorks

开源 远程办公 即时通讯 IM

一个完整的项目管理流程包括什么?

万事ONES

项目管理 ONES

小白也能看懂的Java内存模型

程序猿阿星

JMM Java内存模型 原子性 有序性 可见性;

手写链表之LinkedList源码分析

Ayue、

数据结构

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