写点什么

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

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

关注

评论

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

Parallels虚拟机专用windows系统镜像(m1/intel) 含win系统安装教程

Rose

pd虚拟机 Mac双系统 win镜像 Parallels Desktop虚拟机

怎样解决注塑行业的难点与现状?

万界星空科技

mes 万界星空科技 万界星空科技mes 注塑MES 注塑行业

ChatGPT:故障频发背后的反思,重新理解稳定性

焦振清

稳定性 稳定性治理 AZ 逃生 蓝军

基于Express的微信公众号开发

派大星

Express 微信公众号开发

如何正确使用 Bean Validation 进行数据校验

得物技术

数据分析

实现高效 Spring RESTful API:最佳实践

Apifox

Java 程序员 Spring Boot 后端 REST API

Slidepad for mac:给你的 macOS 添加一块 iPad 式的悬浮窗口

Rose

Slidepad mac效率软件

网站死链如何查看?Scrutiny for Mac网站分析检测工具来帮你!

Rose

Mac软件 mac网站分析检测工具 SEO 优化 Scrutiny 网站死链

Envoy网格基础概念

蝉翼2u

云原生 服务网格 envoy

sketch文件导出没有背景色怎么办? sketch背景色消失的解决办法

Rose

Sketch下载 sketch无背景 矢量图设计 sketch mac破解版

高效灌溉 - 真正意义的降本增效

zhumingwu

photoshop 2022新功能介绍 含ps2022破解版下载资源

Rose

ps PS2022下载 Photoshop 2022下载 Photoshop 2024破解版

服务网格基础

蝉翼2u

微服务 云原生 服务网格

基于开源IM即时通讯框架MobileIMSDK:RainbowChat v11.0版已发布

JackJiang

网络编程 即时通讯 IM

【wayn商城】本地开发指南

越长大越悲伤

Java 开源 前端 后端 wayn商城

顺丰科技智慧供应链助力自动化立体仓库建设

新消费日报

试用强大的百度智能云【AI原生应用工作台】实现《毛泽东传记问答》实操记录

livingbody

AI BAIDU 知识库 人工智能「 知识库问答

百万级监控指标的秒级采集与处理

鲸品堂

监控 解决方案

Wireshark网络工具是什么?

小齐写代码

每日一题:LeetCode-739. 每日温度

Geek_4z9ami

Go 面试 算法 LeetCode 单调栈

用Java实现冒泡排序:实用教程带你入门

SoFlu软件机器人

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