2.1 一致的编码风格
风格一致是对代码最基本的要求,门槛不高。在养成好的编程习惯、建立好的编程规范之后,风格一致是很容易做到的。形象地说,风格一致指的是“代码看上去像同一个人写出来的”。
2.1.1 需要一致的编码风格
为什么把一致的编码风格列为第一条呢?这是因为,代码是软件开发活动中最基本的信息媒介。没有人希望看到一段代码是一种布局,换一段代码就变成了另外一种布局。也没有人希望看到在一个地方是一种异常处理方式,在另外一个地方又是另一种。类似的情况还有很多。
从空间维度讲,绝大多数软件组织的软件开发是以团队为单位进行的,需要许多开发者同时参与。从时间维度讲,一段代码的生命周期往往会跨越很长的时间,甚至会持续十几年、几十年。如果代码的风格不一致,那么很难想象开发者能在不同的代码风格之间无障碍地工作。不一致的编码风格会对代码的可理解性、可维护性产生非常大的影响。此外,从心理角度讲,风格不一致的代码会给人一种“敷衍”的感觉,使他们很难静下心来精心打磨设计。
2.1.2 通过编程规范约束编码风格
我们通常以编程规范的形式约束编码风格。编程规范是一个团队对代码风格做的约定。要想有效实施编程规范,需要注意如下3个方面。
有成文的编程规范。
团队成员对编程规范的约定有深刻的理解。
编程规范是团队资产的一部分,会被刻意关注并持续演进。
“有成文的编程规范”是一个非常基础的要求。这正如法律条文一样,首先得“有法可依”,才能做到“执法必严”。大公司往往拥有非常体系化的编程规范,如《阿里巴巴Java开发手册》[6],该文件不仅在阿里巴巴内部具有重要影响,也影响了许多外部企业的开发者。对于一些尚未建立编程规范的企业和团队而言,选择一个与自己技术栈类似的大企业的编程规范作为基础,常常是一个好的起点。
编程规范并不是一堆刻板的条文,而是最佳经验的总结。例如,在《阿里巴巴Java开发手册》的“集合处理”一节中,约定了hashCode和equals的重写必须一致、建议使用entrySet遍历Map而不是用keySet遍历等,这些要么和代码的正确性相关,要么和代码的执行效率相关。开发者除了要遵循编程规范,更要懂得编程规范背后的逻辑。只有理解了逻辑,才能真正地做到有效实施,并且保持编程规范的持续演进。
2.1.3 编程规范也要持续演进
既然编程规范体现了团队的经验总结,那么随着时间的推移,团队必然会积累新的经验和教训,这时编程规范也应该同步演进。
扩展阅读
《阿里巴巴Java开发手册》从2017年2月发布第一个正式版本开始,到2020年8月,短短的3年半时间,就先后发布了12个版本,特别是在1.4. 0版本、1.5. 0版本、1.6. 0版本和1.7. 0版本中均增加了数量可观的规范(分别新增14条、21条、34条和14条)。这些增加的规范,往往来自团队认知水平的提升,这种提升以编程规范的形式获得了沉淀,从而为后续的开发活动提供支持。
2.1.4 通过代码评审和结对编程统一编码风格
编程规范在统一编码风格方面具有重要的作用,但它毕竟不可能覆盖代码的方方面面。在实践中,更多的统一是团队在日常的开发活动中逐渐形成的。例如,代码评审和结对编程就是两个统一编码风格非常有效的活动。
代码评审是一个大家普遍认为非常有效的活动,但落地实施需要很多技巧。结对编程来自极限编程[7],是一种非常有效的编程实践,尽管不少人对它持有怀疑态度,可是一旦能成功在团队中实施,收益还是非常明显的。结对编程不只是统一了编码的风格,也不只是一种“即时”的代码评审,其更重要的意义在于由它引发的密集交流,必然能更好地传播知识、产生更少的错误和编写出更易读的代码。本书的10.4节会进一步介绍代码评审和结对编程。
2.1.5 编程规范示例
约定编程规范本身是一个专门的工作。本书仅给出典型的编程规范示例,更多具体的编程规范,请读者参阅相关技术书籍。
统一编码风格
风格类的编程规范,重点在于保证代码的可读性和风格的一致性。例如,如何使用空格、如何命名、如何使用大小写、是使用驼峰还是下划线、如何使用大括号,等等。比如在《阿里巴巴Java开发手册》中,关于在代码中应该使用Tab字符还是空格做了如下约定。
【强制】采用4个空格缩进,禁止使用Tab字符。
这个约定背后的考量,是Tab字符对应的空格数可以在编辑器中自定义。有些程序员可能把它设置为4个空格,有些程序员可能设置为8个。如果混用空格和Tab字符,那么在Tab字符对应4个空格的编辑器中正常显示的代码,在Tab字符对应8个空格的编辑器中会显示混乱。还有些编程规范中约定仅允许使用Tab字符,不允许使用空格,也能达到相同的效果。
传播最佳实践
在编码过程中会持续碰到一些典型情况,如前文提到的hashCode和equals,如果不成对出现就可能出现问题。这些情况能否得到正确处理和代码质量密切相关。为了保证编程规范的最佳实践能够得以实施,我们常常以编程规范的形式把它们总结成文,这类编程规范的例子有抛出异常的策略、日志记录的策略等。
我们仍然以《阿里巴巴Java开发手册》为例,来看其中的一条约定。
【推荐】使用JDK8的Optional类来防止NPE问题。
NPE指的是空指针错误(Null Pointer Error)。Optional类的核心目标就是避免NPE问题。类似这样最佳实践的问题,手册中常常使用“推荐”这个级别的编程规范进行约定。另外,该编程规范中的约束和建议还包括如何处理集合、如何使用数据库、如何构建项目的工程结构和二方库依赖、如何编写合格的单元测试等众多最佳实践和团队级约定。编程规范不仅体现了编码风格的一致性,也让团队成员积累的经验以编程规范的形式成为了团队资产。