作为软件开发者,我们每天都会写出大量代码。每一段代码都有自己的故事。它可能是:
- 受网络资源(论坛、教程、博客文章等)启发而写成的。
- 受 GitHub、SourceForge 或其他地方的开源项目启发而写成的。
- 从项目自身复制粘贴而来的。
- 从零开始开发的。
对于每一段代码,开发者都要分析待解决的问题。开发者的背景以及团队的意见会极大地影响其选择和代码的编写方式。
写完并提交代码后,请记住,它可能会引入技术债,项目的维护者和开发者迟早都要处理这些债务。为了尽量减少技术债,让项目中的每个人都更轻松,最好养成一些从一开始就保持代码整洁的好习惯。
1. 命名
有时我们花大量时间只是为了弄清楚一个变量或函数的用途,因为它被命名为 a、b 或 x。如果从一开始就起一个清晰、有意义的名字,其含义就会一目了然。
遵循一致命名规范的清晰、有意义的名字有助于:
- 减少阅读和理解源代码所需的工作量;
- 让代码评审聚焦于更重要的问题,而不是围绕语法和命名规范争论不休。
- 让代码质量工具的报告聚焦于重要问题,而不是语法和风格偏好。
2. 可见性
缩小可见性是一个好习惯,因为它能促进封装。将作用域保持在最小范围,有助于代码使用者准确了解哪些成员是供类外部访问的。
把类的所有方法都设为 public 会让使用者困惑,也会模糊类的契约;在这种情况下,只能依靠文档来确定哪些方法才是打算对外使用的。
3. 参数
一个函数如果接受超过五个参数,说明存在以下两种问题之一:
- 该函数做的事情太多了。应该把它拆分成若干更小的函数,每个函数的参数集更小。
- 里面还隐藏着另一个对象。您可能需要创建另一个包含这些参数的对象或数据结构。
这样做有以下几个好处:
- 让代码更易读。
- 让单元测试更容易。

4. 大小
过长的方法不易于维护和理解。下面是来自Linux 编码风格网页关于函数长度的一些建议:
Functions should be short and sweet, and do just one thing. They should
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
as we all know), and do one thing and do that well.
The maximum length of a function is inversely proportional to the
complexity and indentation level of that function. So, if you have a
conceptually simple function that is just one long (but simple)
case-statement, where you have to do lots of small things for a lot of
different cases, it's OK to have a longer function.
5. 局部变量数量
NbVariables 大于 8 的方法难以理解和维护。NbVariables 大于 15 的方法则极其复杂,应当拆分成更小的方法(除非它们是由工具自动生成的)。

6. 避免定义复杂函数
有许多度量可用于检测复杂函数;代码行数(NBLinesOfCode)、参数数量和局部变量数量是最基本的几个。
其他有用的度量也可以帮助识别复杂函数:
- 圈复杂度是一种流行的过程式软件度量,其结果等于一个过程中可能发生的决策数量。
- 嵌套深度是一种方法级度量,表示方法体内嵌套作用域的最大深度。
- 最大嵌套循环数等于函数中循环嵌套的最大层数。
这些度量的最大可接受值在很大程度上取决于团队的偏好,因为没有放之四海皆准的阈值。
让我们找出可能需要重构的函数:

7. 格式
编程风格和缩进可以定义为您组织源代码并为其编写文档的方式。代码缩进是编程风格的一部分,很大程度上关乎可读性与美感。如果我们遵循恰当的风格指南和缩进,程序就能像一首诗(POEM)一样,读者可以轻松愉快地“扬帆(SAIL)”通读并理解其含义。众所周知,恰当的代码缩进会让代码:
- 更易读
- 更易理解
- 更易修改
- 更易维护
- 更易增强
代码缩进和风格的目的在于让程序更易读、更易理解。当我们重新检视或复用代码时,这会节省大量时间。风格指南为开发者提供了一份编码时应遵循的路线图,这样在一个开发者团队中,产出的所有代码在本质上保持一致,任何开发者都能复用。
8. 注释
有时代码完全没有注释,而另一些时候又注释过多。也许您已经读过这句话:好的代码本身就是文档。
是的,保持代码整洁、让它自己说话、避免注释,确实是好做法——但在现实世界中,这并不总是容易做到。在某些情况下,您需要澄清代码到底做了什么。
9. 耦合
低耦合是可取的,因为应用程序某一处的变更,需要其他地方的改动也会更少。从长远来看,这可以减少修改应用程序和添加新功能所需的时间、精力和成本。
依赖众多其他函数的函数可能难以理解和维护。建议尽量减少函数的传出耦合(efferent coupling)。

10. 内聚
单一职责原则指出,一个类不应有超过一个变更理由。这样的类被称为内聚的。较高的 LCOM 值通常表明类的内聚性较差。LCOM 度量有好几种。LCOM 的取值范围是 [0-1];LCOM HS(HS 代表 Henderson-Sellers)的取值范围是 [0-2]。LCOM HS 值高于 1 就应视为警讯。下面是 LCOM 度量的计算方法:
LCOM = 1 – (sum(MF)/M*F) LCOM HS = (M – sum(MF)/F)(M-1)
其中:
- M 是类中方法的数量(静态方法和实例方法都计入;还包括构造函数、属性的 getter/setter 以及事件的 add/remove 方法)。
- F 是类中实例字段的数量。
- MF 是访问某个特定实例字段的类方法数量。
- Sum(MF) 是类中所有实例字段的 MF 之和。
这些公式背后的基本思想可以这样表述:如果一个类的所有方法都使用它的所有实例字段,那么这个类就是完全内聚的,也就是说 sum(MF)=M*F,此时 LCOM = 0 且 LCOMHS = 0。
LCOMHS 值高于 1 就应视为警讯。

结语
这些是一些能帮助您从一开始就保持代码整洁的基本习惯。不要等到大规模重构时才去清理——试着从一开始就保持整洁。
