IBM 文摘 ———— 大牛很好的经验总结

编写优良的 Java 代码

介绍

您现在已经了解了很多 Java 语法,但是这并不是专业编程的真正主题。什么造就“优良的”Java 程序呢?

也许有多少专业 Java 程序员,这个问题就有多少种答案。但是我有一些建议,我相信大多数专业 Java 程序员都赞同,可以改善他们日常处理的 Java 代码的质量。开诚布公地说,我推崇像极限编程(Extreme Programming,XP)这样的灵巧方法,所以我的许多关于“优良”代码的观点一般是受灵活社团(agile community )的鼓动,尤其是受 XP 的影响。我依然认为大多数有经验的专业 Java 程序员会赞同我将在本节中提出的观点。

保持类最小

在本教程中,我们创建了一个简单的 Adult 类。即使在将 main() 方法移动到另一个类之后,Adult 还剩下 100 多行代码。它具有 20 多个方法,但是将它与您可能看到(和创建)的许多类从专业的角度来进行比较,它其实并没有做多少事情。这是一个 类。具有 50 到 100 个方法的类并不少见。还有什么比拥有较少的类更坏的事情吗?可能不会再有了。当然,最好还是有满足自己需要的类。如果您需要几个本质上完成相同事情但带有不同参数的助手方法(比如 addMoney() 方法),那就是最好的选择。只是一定要限制需要的方法列表,除此之外,其他都按需行事。

一般来说,一个带有大量方法的类总是具有一些不属于这里的方法,因为这个庞大的对象所做的事情太多了。Martin Fowler 在他的 Refactoring一书中(参见 参考资料 中的链接), 将这称为 Foreign Method 代码味道。如果您有一个带有 100 个方法的对象,就应该好好想想,这个对象是否应该拆成多个对象。大类通常在大学里大行其道。Java 代码与之一样。

保持方法最小

小方法就与小类一样可取,并且原因也类似。

很多有经验的 OO 程序员对 Java 语言具有的苦恼之一就是,它提供大量的 OO 能力,但是却没有教他们如何做好 OO。换句话说,它给了他们很多绳子去捆绑自己(尽管至少没有 C++ 给他们的多)。能看到这一点的一个常见地方是 main() 方法离得很远的类,或者一个单个的名叫doIt() 的方法。仅仅因为能够 将所有的代码放在类中的单个方法中,并不意味着就应该 如此。Java 语言比很多其他 OO 语言具有更多的语法糖,所以一定的罗嗦是必要的,但是不要过了度。

思考一下这些超长的方法。滚动十屏代码去了解代码所做的工作是很艰难的。该方法做什么工作?您需要泡上一杯大大的咖啡花几个小时去研究才能知道。一个小的,甚至微小的方法是一个容易看懂的代码块。运行时效率不是要具有小方法的原因,可读性才是真正的目标。这将使得代码更加容易维护,并且在需要添加功能时更加容易更改。

将每个方法局限于执行一项工作。

给方法取好名称

我曾经见到过的最佳编码模式(忘了是在哪里见到的了)叫做揭示意图的方法名。下面两个方法名中哪个更容易一眼看出意图?

  • a()
  • computeCommission()

答案很明显。出于某些原因,程序员似乎讨厌长的方法名。过长的方法名无疑是不方便的,但是长到足够明了通常不是过长。我觉得像aReallyLongMethodNameThatIsAbsolutelyClear() 这样的方法名是可以接受的。如果在凌晨 3 点,我试图找出程序为什么不工作时,遇到一个名叫 a() 的方法,那我真想揍人。

额外花几分钟想出一个非常具有描述性的方法名;如果可能,考虑以这样的方式命名方法,即让代码阅读起来更像英文,即使这意味着添加附加的助手方法来做这项工作。例如,考虑添加一个助手方法以使得代码更加可读:

if (myAdult.getWallet().isEmpty()) {
	do something
}

ArrayList 上的 isEmpty() 方法本身是有帮助的,但是我们的 if 语句中的布尔条件应该像下面这样得益于 Adult 上一个叫做 hasMoney() 的方法:

public boolean hasMoney() {
	return !getWallet().isEmpty();
}

然后我们的 if 语句读起来更像英文:

if (myAdult.hasMoney()) {
	do something
}

这一技巧很简单,也许在本例中是微不足道的,但是当代码变得越来越复杂时,它就会显露出惊人的威力。

保持类的数量最少

XP 中关于简单设计的其中一个指导方针是,用尽可能少的类完成一个目标。如果您需要另一个类,尽管添加就是了。如果另一个类将使得代码更简单或者简化您的意图表达,那么就添加这个类吧。但是没有理由只是为了具有而具有类。当然,通常项目早期比结束时具有的类要少,但是一般将代码重构成更多的类比组合类更容易。如果您有一个具有大量方法的类,那么分析一下,看是否有另一个对象陷入在其中,正在等待出去。如果有的话,就创建一个新的对象。

在我经历的几乎所有 Java 项目上,没有人害怕创建类,但是我们也总是试图在不降低意图清晰度的情况下,减少类的数量。

保持注释的数量最少

我过去常常在代码中编写很多的注释,读起来就像一本书。后来我变得聪明一些了。

每一个计算机科学程序、每一本编程书籍和我知道的很多程序员,都要您给代码编写注释。在有些情况下,注释是有帮助的。在许多情况下,注释使得代码维护更加困难。想想您更改代码时必须做什么。有注释吗?如果有的话,您最好更改注释,否则它会可怕地过期,甚至随着时间的推移,根本就不再能够描述代码。依我的经验,几乎会使维护时间加倍。

我的经验法则是:如果代码太难阅读和理解而需要注释,我就需要使它足够清晰,从而不需要注释。代码可能会太长,或者做太多的事情。如果这样的话,我就简化它。代码可能太隐晦。如果这样的话,我就添加助手方法,使之清晰。实际上,在与同一团队的其他成员一起进行 Java 编程的三年当中,我所编写的注释屈指可数。保持代码清晰!如果您需要系统或者某个特定组件的全景描述,就编写一个简短的注释来描述。

罗嗦的注释一般比较难维护,通常不及一个小的、编写良好的方法那么好地表达意图,并且很快就会过期。根本不要过分依赖注释。

使用一致的风格

编码风格实际上是您的环境中必然的并且可接受的东西。我甚至不知道哪一种风格可以称为“典型的”。这通常是个人品味问题。例如,下面是一些让我看到会难受的代码:

public void myMethod()
{
	if (this.a == this.b)
	{
		statements
	}
}

为什么这会烦扰我呢?因为我个人偏向于反对那些添加我认为不必要的代码行的编码风格。Java 编译器认为下面的代码与刚才的代码完全相同,而我减少了几行:

public void myMethod() {
	if (this.a == this.b)
		statements
}

二者没有“对”或“错”之分,只是一个比另一个短一些。那么当我与某个喜欢第一种形式的人一起编码时会怎么样?我们进行协商,挑选出一种来,然后一直坚持用这一种。惟一绝对的风格规则是一致性。如果一个项目上的每个人都用不同的风格,那么阅读代码将变得很困难。挑选一种风格并且不要改变。

避免 switch

一些 Java 程序员对 switch 语句情有独钟。我曾经认为它们很好,但是后来我认识到了,一个 switch 实际上就是几个 if,并且通常意味着条件逻辑出现在代码中的多个地方。这是代码重复,是应该禁忌的。为什么?因为在多处具有相同的代码使得代码比较难更改。如果我在三处具有相同的 switch,并且想要更改对某个 case 的处理,我就得在三处更改代码。

现在,如果您可以重构具有单个 switch 语句的代码,那会怎么样呢?很好!我不相信使用它有什么坏处。在有些情况下,它比嵌套的 if 更清晰。但是如果您看到它出现在很多地方,就有了应该解决的问题了。防止这一问题的一个容易的方法是,避免 switch,除非它对于该工作是最佳的工具。依我的经验,它很少是最佳的。

是 public 的

我把最具争议的建议放在最后。做一下深呼吸。

我相信您会反对让所有的方法都是 public 的。实例变量应该是 protected 的。

当然,许多专业程序员会害怕这种想法,因为如果任何东西都是公共的,那么任何人都可以更改它,也许会以未授权的方式更改。在任何东西都是公共可访问的世界中,您就不得不依赖于程序员纪律,以确保人们在其不应该访问时不会访问其不应该访问的东西。但是在编程生活当中,很少有什么事情比想要访问一个不可见的变量或方法更受挫的了。如果您对代码中您设想其他人不应该访问的东西限制访问,您就是在设想自己无所不知。这在大多数时候是一个危险的假设。

当使用其他人的代码时,这种受挫感会经常出现。您会看到一个方法刚好做您想要做的工作,但是它不是公共可访问的。有时,这有一个很好的原因,并且使得限制可访问性有意义。但是有时,不 public 的惟一原因是,编写代码的人这样想“没有人需要访问该代码”,或者他们这样想“没有人应该访问该代码,因为……”,于是他们并没有很好的理由。许多时候,人们使用 private 是因为它可用。不要这样做。

使方法是 public 的,变量是 protected 的,直到您有一个很好的理由限制访问。

追随 Fowler

现在您知道了如何创建优良的 Java 代码,以及如何保持它优良。

关于该主题,业界最好的书籍是 Martin Fowler 编著的 Refactoring (参见 参考资料 中的链接)。它读起来甚至很有趣。重构(refactoring) 的意思是在不改变代码结果的情况下,更改现有代码的设计。Fowler 谈论了请求重构的“代码气味”,并且详细介绍了用于改变“代码气味”的各种技巧(或者“重构”)。依我的观点,重构和编写一次通过测试的代码的能力(参阅 参考资料)是新手程序员要学习的最重要的技能。如果每个人都擅长于这两点,那将彻底改变行业当前的局面。如果 擅长于这两点,就会比较容易找到工作,因为您能比其他人产生更好的结果。

编写 Java 代码相当简单。编写优良的 Java 代码则是一门手艺。倾力成为一个手艺人。

回页首

结束语

在本教程中,学习了 OOP 和用于创建有用对象的 Java 语法,并了解了一个有助于控制开发环境的 IDE。您可以创建做很多事情的对象,尽管不是您能想像到的每一件事情。但是您可以用几种方式扩展自己的知识,包括通过其他 developerWorks 教程来研究 Java API 和探索 Java 语言的其他功能。请参见 参考资料 中的链接。

Java 语言无疑不是完美的;每种语言都有它的特点,而每个程序员都有自己的喜好。但是 Java 平台是一个很好的工具,可以帮助您编写非常好的专业程序。

时间: 2024-08-02 02:50:53

IBM 文摘 ———— 大牛很好的经验总结的相关文章

大牛很通俗地介绍《信号与系统》

大牛很通俗地介绍<信号与系统> 第一课 什么是卷积 卷积有什么用 什么是傅利叶变换 什么是拉普拉斯变换  引子很多朋友和我一样,工科电子类专业,学了一堆信号方面的课,什么都没学懂,背了公式考了试,然后毕业了. 先说"卷积有什么用"这个问题.(有人抢答,"卷积"是为了学习"信号与系统"这门课的后续章节而存在的.我大吼一声,把他拖出去枪毙!) 讲一个故事:   张三刚刚应聘到了一个电子产品公司做测试人员,他没有学过"信号与系统&

收藏一下大牛的数据挖掘学习经验

只是过来人,说点看法: 基础篇: 1. 读书<Introduction to Data Mining>,这本书很浅显易懂,没有复杂高深的公式,很合适入门的人.另外可以用这本书做参考<Data Mining : Concepts and Techniques>.第二本比较厚,也多了一些数据仓库方面的知识.如果对算法比较喜欢,可以再阅读<Introduction to Machine Learning>. 2. 实现经典算法.有几个部分:a. 关联规则挖掘 (Apriori

【转载】大牛很通俗地介绍《信号与系统》

转载地址:http://emuch.net/bbs/viewthread.php?tid=4009368&fpage=1 第一课 什么是卷积 卷积有什么用 什么是傅利叶变换 什么是拉普拉斯变换  引子       很多朋友和我一样,工科电子类专业,学了一堆信号方面的课,什么都没学懂,背了公式考了试,然后毕业了.   先说"卷积有什么用"这个问题.(有人抢答,"卷积"是为了学习"信号与系统"这门课的后续章节而存在的.我大吼一声,把他拖出去枪

揭秘IBM的世纪转型,访IBM大中华区董事长陈黎明

(上图为IBM大中华区董事长陈黎明) 到2017年2月,陈黎明已经在IBM大中华区董事长的任上整整两年了.五年前,IBM历史上首位女CEO也是第9位CEO罗睿兰上任,三年前IBM在罗睿兰的带领下以数据与分析.云.社交.移动和安全为战略方向,展开了云与大数据时代的历史性转型.2016年,IBM股价大涨了45%,初显本次战略转型成功,其中当然也有来自大中华区的贡献. 2017年2月28日,陈黎明接受了笔者的独家专访,披露了过去两年间他在IBM大中华区董事长任上所做的具体工作以及相应成效.这些一手资料

微软八年转折近尾声,总结向云转型54条经验

(上图2016微软全球合作伙伴大会吸引了144个国家的云解决方案商参会) 2016年7月14日,历时三天的微软全球合作伙伴大会WPC 2016在加拿大多伦多落下帷幕,来自全球144个国家的16,000名软件开发商(ISV).系统集成商(SI).增值分销商(VAR)以及新一代云服务商(CSP)等汇聚一堂,他们也是全球最活跃.最顶尖的云计算生态代表. 在本次合作伙伴大会上,微软发布了合作伙伴"红宝书"--<当代微软合作伙伴系列:解决方案商如何在云世纪成功>.这本与IDC合作的书

天天写业务代码,如何成为技术大牛

前序 在工作之余浏览公司的技术网站,看到了以下这篇文章,细细读来真心觉得不错,写得有价值很实在.于是想联系下作者,问一下是否可以转载.打开钉钉一搜,作者是资深技术专家,差不多就是技术总监级别啊,这也从侧面旁征了,以下的内容是有其亲身经历,切实体会的,而不是鸡汤口号之流.相较与作者的级别,自己确实惭愧汗颜,所以没好直接聊天询问而是在文章底下留言.在得到了作者的同意后将文章的内容贴到这里,作为分享也作为自己的鞭策和提醒.在这里谢谢我的大牛同事了^_^. ....................以下内

记录参加CSDN大牛上海大联欢活动

今天很荣幸参加CSDN技术大牛上海聚会,首先申明一点我只是一个不起眼的小程序员,首先就是要感谢CSDN给我这么一个机会认识了一些老一辈的技术大牛老师,包括百姓网联合创始人潘老师,爱奇艺.携程.饿了吗.中兴.华为.点评.完美.乐元素.因特尔.百度等等技术经理,涉及到java..net.C++.unity.php.云计算.大数据等等各行各业的技术专家,能做为一名为数不多的90后程序员晚辈参加这次盛宴,感觉是给我的新年的最好的一个礼物.感谢CSDN的钱总的邀请和准备使得每个人在这次的"腐败"

天天写业务代码,如何成为技术大牛?

不管是开发.测试.运维,每个技术人员心理多多少少都有一个成为技术大牛的梦,毕竟"梦想总是要有的,万一实现了呢"!正是对技术梦的追求,促使我们不断地努力和提升自己. 然而"梦想是美好的,现实却是残酷的",很多同学在实际工作后就会发现,梦想是成为大牛,但做的事情看起来跟大牛都不沾边,例如,程序员说"天天写业务代码还加班,如何才能成为技术大牛",测试说"每天都有执行不完的测试用例",运维说"扛机器接网线敲shell命令,这

如何成为技术大牛

不管是开发.测试.运维,每个技术人员心理多多少少都有一个成为技术大牛的梦,毕竟"梦想总是要有的,万一实现了呢"!正是对技术梦的追求,促使我们不断地努力和提升自己. 然而"梦想是美好的,现实却是残酷的",很多同学在实际工作后就会发现,梦想是成为大牛,但做的事情看起来跟大牛都不沾边,例如,程序员说"天天写业务代码还加班,如何才能成为技术大牛",测试说"每天都有执行不完的测试用例",运维说"扛机器接网线敲shell命令,这