2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

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

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

关注

评论

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

一文带你了解EiPaaS和EiPaaS的国际趋势

华为云开发者联盟

云计算 后端 华为云 12 月 PK 榜

MegEngine Windows Python wheel 包减肥之路

MegEngineBot

深度学习 开源 MegEngine

YonBuilder移动开发平台 AVM框架 封装省市区级联选择弹框

YonBuilder低代码开发平台

开发者 AVM

为什么数字化时代需要 BizDevOps?

阿里云云效

DevOps 数字化转型 数字化 BizDevOps

GitHub标星已达26K+,鹅厂技术总监手写分布式架构体系笔记

小小怪下士

Java 程序员 分布式

火山引擎DataTester科普:A/B实验常见名词解释

字节跳动数据平台

大数据 AB testing实战 12 月 PK 榜

阿里二面被问MySQL的事务隔离级别,结果回去等通知了

程序员小毕

MySQL 数据库 程序员 面试 后端

如何在小程序中完成支付进件

Towify

微信小程序 编辑器 无代码

学习大数据培训和自学哪个比较好

小谷哥

前端编程学习有没有必要参加?

小谷哥

OSCS开源安全周报第22期:NuGet 仓库中被发现 13.5 万个包含钓鱼地址的组件包

墨菲安全

【电路设计】避开元器件的这些“坑”,多年的心梗都治好了!

华秋PCB

工具 PCB PCB设计

皮皮App发起爱心捐赠,让城市里的荧荧之光,给乡村孩子带去一片暖冬

联营汇聚

前端程序员培训学习需要学多久?

小谷哥

建筑、工程和施工产业中的3D可视化

3DCAT实时渲染

可视化 云渲染 实时云渲染 云渲染平台

Spring中11个最常用的扩展点,你知道几个?

JAVA旭阳

Java spring

西藏等保测评公司有哪些?共有几家?

行云管家

等保测评 等保测评公司 西藏

一文读懂于Zebec生态中的潜在收益方式

鳄鱼视界

大数据开发技术培训班怎么选

小谷哥

调试3D渲染和3D可视化的五个好处

3DCAT实时渲染

可视化 3D渲染 云渲染 实时渲染

部分双机热备软件详细介绍-行云管家

行云管家

高可用 双机热备 双机

HIFIVE音加加提供曲库、评分、修音功能的K歌SDK-Android版本

数到3变暖男i

API 社交泛娱乐 娱乐社交 K歌 K歌SDK

如何通过 NFTScan 发掘 NFT 项目的内在价值

NFT Research

区块链 NFT

行业认可|墨菲安全登信息通信软件供应链安全社区优秀榜单

墨菲安全

参加java培训对学习程序员有用吗?

小谷哥

“2022混合云TOP50”重磅发布 天翼云问鼎榜首

极客天地

AI与低代码的结合及应用

力软低代码开发平台

如何用 7 分钟玩转函数计算?

阿里巴巴云原生

阿里云 Serverless 云原生

TDengine与中泰证券正式签约,打造金融量化交易场景解决方案

TDengine

数据库 tdengine 时序数据库

游戏引擎中的实时渲染和在V-Ray中渲染有什么区别?

3DCAT实时渲染

渲染引擎 游戏引擎 渲染服务 游戏开发引擎

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