`
shuai1234
  • 浏览: 932463 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

Java编程风格的改变

阅读更多



最近Stephan Schmidt在博客中发表了题为《下一代Java编程风格》的文章,阐述了他眼中Java编程风格的改变,以及未来的走向:许多公司和开发人员正在从Java转向其他编程语言:Ruby、Python、Groovy、Erlang或Scala等等。不过你可能做不到这一 点。即便如此,你也可以改变你的编程风格,获取这些新语言的优势。事实上,在过去的15年中,Java编程风格也已经有明显变化了。

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

尽可能地标注final:让所有东西不可变,把变量标为final可以阻止改变它的值。很多时候,重新为变量赋值会引入bug,你应该使用新的变量。除此之外,final可以提高代码的可读性。我针对这个话题还写过一篇文章:《Java中所有变量都应该是final的》
没有setter:许多Java程序员会自然而然地为类中所有的字段加上setter。思考一下,真的每个字段都需要修改吗?更好的方法是创建包含改变后状态的新对象。此外,也试着去除getter,我们应该遵循“Tell, don’t ask”的思想。
避免使用循环来操作List:从函数式编程那里获得的经验,循环并不是进行集合操作最好方法。例如,我们可以使用Google Collections提供的过滤功能。
Predicate canDrinkBeer = new Predicate() {     public boolean apply(HasAge hasAge) {         return hasAge.isOlderThan( 16 );    }};List<Person> beerDrinkers = filter(persons, canDrinkBeer);使用单行代码:Java是一门繁杂(noisy)的语言,我们应该编写更精确的代码。尝试将代码写为一行。例如:
public int add(int a, int b) { return a + b; }使用大量接口:领域驱动设计已经大行其道,一个应该拆分为多种“角色”,即实现多种接口,提高复用程度。方法应该面向“角色”,而不是面向特定的类。我在《不要在Java中使用String》一文中讨论了更多这方面的内容。
使用Erlang风格的并发:Java的并发特性(如lock和synchronized)过于低端,难以使用。Erlang风格的并发是一种更好的做法。Java平台上已经有了Akka和Actorom。此外,也可以使用java.util.concurrent中的Join/Fork和数据结构进行编程。
使用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);            }        });避免在DTO中创建getter和setter:如果你拥有简单的DTO(Data Transfer Object),不要耗费精力去编写getter和setter,直接使用公开的字段吧。不过在你无法完全控制代码的使用情况时,还是小心为上。
这篇文章发表之后,有许多人发表了不同的看法。其中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编程风格是什么样的,和过去相比有什么改变吗?
分享到:
评论

相关推荐

    Java编程思想(完整版)

    杂合语言允许采用多种编程风格;之所以说C++是一种杂合语言,是因为它支持与C语言的向后兼容能力。由于C++是C的一个超集,所以包含的许多特性都是后者不具备的,这些特性使C++在某些地方显得过于复杂。 Java语言首先...

    基础深化和提高-java函数式编程

    Lambda表达式使得Java可以支持以更简洁的方式定义匿名函数,从而能够更方便地进行函数式编程风格的编程。Stream API 则提供了对集合数据进行流式操作的功能,包括过滤、映射、归约等。 函数式编程的特点包括: 高...

    Java 中的简单文本编辑器源代码

    Java 中的简单文本编辑器是用 Java 编程语言编码的桌面应用程序。该项目使用一个简单的函数来制作文本编辑器应用程序。这个项目可以允许写任何字母...这个 Java 中的简单文本编辑器提供了一种新的 Java 编程编码风格。

    h_JAVA 2应用编程150例.rar

    第1章 Java图形用户界面编程 1 实例1 布局管理 2 实例2 设计软件启动界面 9 实例3 实现多色窗口 11 实例4 切分窗口 13 实例5 丰富多彩的按钮 15 实例6 在窗口中显示背景图 16 实例7 在窗体中绘制图形 18 实例8 利用...

    java应用软件程序设计

    37 实例16 使用进度条 39 实例17 使用工具提示 42 实例18 不同界面的风格 43 第2章 Java的二维和三维图形处理 45 实例19 颜色处理 46 实例20 合成效果 47 实例21 多种字体效果 49 实例22 ...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    3.1.5 值改变事件 125 3.1.6 生命周期事件 128 3.1.7 将监听器绑定到Bean属性 130 3.2 JSF的国际化支持 132 3.2.1 加载国际化资源文件 132 3.2.2 使用国际化消息 134 3.2.3 动态数据国际化 137 3.2.4 让用户选择语言...

    java学习笔记 初学者必读

    7.6.1. final变量不能被改变; 7-22 7.6.2. final方法不能被改写; 7-23 7.6.3. final类不能被继承; 7-23 7.6.4. String 类 7-23 7.7. 抽象类 7-24 7.8. 接口 (模板方法模式) 7-25 7.9. Object 类 7-27 7.10. 封装类 7...

    corejava培训文档

    7.6.1. final变量不能被改变; 7.6.2. final方法不能被改写; 7.6.3. final类不能被继承; 7.6.4. String 类 7.7. 抽象类 7.8. 接口 (模板方法模式) 7.9. Object 类 7.10. 封装类 7.11. 内部类 7.11.1. ...

    java面试题

    描述你的编程风格? 答:类名首字母大写,常量一般全部大写,给自己的代码加注释。 控制流程? 答:控制流程一般使用if判断条件。有第二分支,多分支,循环结构。循环本质上也是通过判断来实现的。 多形与继承? 答...

    基于Java的愤怒的小鸟游戏的设计与实现

    Java语言是一门面向对象的编程语言,它不但汲取了C++语言的各种精髓,而且还抛弃了C++语言里晦涩难懂的多继承和指针等概念,所以Java语言具有的特征便是:功能超强和易用实用。 Jbox2D中不仅集成了大量物理运动学和...

    基于Java的愤怒的小鸟游戏的设计与实现【LW文档+PPT+开题报告+数据库+讲解视频】

    Java语言是一门面向对象的编程语言,它不但汲取了C++语言的各种精髓,而且还抛弃了C++语言里晦涩难懂的多继承和指针等概念,所以Java语言具有的特征便是:功能超强和易用实用。 Jbox2D中不仅集成了大量物理运动学和...

    Java开发技术大全 电子版

    第2篇Java面向对象编程 第3章对象和类98 3.1面向对象的基本概念98 3.1.1对象98 3.1.2类99 3.1.3消息101 3.1.4面向对象的4个基本特征101 3.2类与对象104 3.2.1类的基本结构104 3.2.2类的声明104 3.2.3创建...

    corejavaNoteBook

    7.6.1. final变量不能被改变; 7-22 7.6.2. final方法不能被改写; 7-23 7.6.3. final类不能被继承; 7-23 7.6.4. String 类 7-23 7.7. 抽象类 7-24 7.8. 接口 (模板方法模式) 7-25 7.9. Object 类 7-27 7.10. 封装类 7...

    Tcl_TK编程权威指南pdf

    使用rename来改变命令名 作用域 global命令 通过upvar以名字进行调用 使用upvar来处理变量别名 第8章 tcl数组 数组的语法 array命令 使用数组来构建数据结构 第9章 对文件和程序的操作 使用exec运行程序...

    贞龙(BIZOSSCMS)高性能内容管理系统JAVA版 v4.1.rar

    由于BIZOSS-CMS是基于JAVA的跨平台编程语言,对于以上两种主流的操作系统都有很好的支持,对于各个IDC提供的空间都有很好的兼容性。 3. 低维护成本 开发一个网站大家都知道需要动用大量的人力物力,不单单开发时...

    Struts2权威指南完整版

     本书适用于有较好的Java编程基础,有一定JSP、Servlet等Web编程基础或具备初步Java EE编程基础的读者。本书既给出了Struts 2入门级的示范实例,也详细讲解了Struts 2各个知识点及各个选项的详细用法,可以作为...

    legendshop2.1源码

    LegendShop是基于JAVA编程语言开发的开源电子商务软件,采用Struts、Hibernate、Spring/Spring MVC等开源技术和自主框架技术开发。 1、LegendShop采用HTML伪静态生成技术和多级缓存技术,使得系统的响应速度和负载...

Global site tag (gtag.js) - Google Analytics