《代码整洁之道》第三章

15 Dec 2021

Reading time ~12 minutes

函数是所有程序中的第一组代码。

3.1 短小

函数的第一条规则是要短小。第二条规则是还要更短小。

代码块和缩进

if语句、else语句、while语句等,其中的代码块应该只占一行,该行大抵应该是一个函数调用语句。

函数不应该大到足以容纳嵌套结构。

3.2 只做一件事

函数应该做一件事。做好这件事。只做这一件事。

要判断函数是否不止做了一件事,就是看它是否能再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。

函数中的区段

只做一件事的函数无法被合理地划分为多个区段。

3.3 每个函数一个抽象层级

要确保函数只做一件事,函数中的语句就要在同一抽象层级上。

自顶向下读代码:向下规则

我们想要让代码拥有自顶向下的阅读顺序。

程序就像是一系列TO起头的段落,每一段都描述当前抽象层级,并引用位于下一层级的后续TO起头段落。

3.4 switch语句

写出短小的switch语句很难。

该问题的解决方案是将switch语句埋藏到抽象工厂底下,不让任何人看到。

3.5 使用具有描述性的名称

函数越短小,功能越集中,就越便于起个好名字。

别害怕长名称。长而具有描述性的名称,要比短而令人费解的名称好。长而具有描述性的名称,要比描述性的长注释好。

别害怕花时间起名字。

选择描述性的名称能理清你关于模块的设计思路,并帮你改进之。

命名方式要保持一致。

3.6 函数参数

最理想的参数数量是0,其次是1,再次是2,应尽量避免3.

参数不易对付。

从测试的角度看,参数甚至更叫人为难。

输出参数比输入参数还要难以理解。

与没有参数相比,只有一个输入参数算是第二好的做法。

3.6.1 单参数函数的普遍形式

向函数传入单个参数有两种极普遍的理由。你也许会问关于那个参数的问题。有可能是操作该参数,将其转换为其他的东西,再输出之。

还要一种虽不那么普遍但仍极有用的单参数函数形式,那就是事件。在这种形式中,有输入参数而无输出参数。程序将函数看作是一个事件,使用该参数修改系统状态。

尽量避免编写不遵循这些形式的单参数函数。

3.6.2 标识参数

标识参数丑陋不堪。向函数中传入布尔值简直就是骇人听闻的做法。

3.6.3 双参数函数

有两个参数的函数要比单参数函数难懂。

当然,有些时候两个参数正好。

3.6.4 三参数函数

有三个参数的函数比双参数函数难懂得多。

3.6.5 参数对象

如果函数看起来需要2个、3个或3个以上得参数,就说明其中一些参数应该封装为类了。

3.6.6 参数列表

有可变参数的函数可能是单参数、双参数甚至三参数的。超过这个数量就可能要犯错了。

3.6.7 动词与关键词

给函数起个好名字,能较好地理解函数的意图,以及参数的顺序和意图。对于单参数函数,函数和参数应当形成一种非常良好的动词/名词对形式。

3.7 无副作用

副作用是一种谎言。副作用会导致古怪的时序性耦合及顺序依赖。

输出参数

普遍而言,应避免使用输出参数。如果函数必须要修改某种状态,就修改所属对象的状态吧。

3.8 分隔指令与询问

函数要么做什么事,要么回答什么事,但二者不可得兼。函数应该修改所属对象的状态,或者返回该对象的有关信息。

3.9 使用异常替代返回错误码

从指令式函数返回错误码略微违反了指令与询问分隔的规则。

如果使用异常替代返回错误码,错误处理代码就能从主路径代码中分离出来,从而得到简化。

3.9.1 抽离try/catch代码块

最好把try和catch代码块的主体部分抽离出来,另外形成函数。

3.9.2 错误处理就是一件事

函数应该只做一件事。错误处理就是一件事。

3.9.3 Error.java依赖磁铁

使用异常代替错误码,新异常就可以从异常类派生出来,而无须重新编译或重新部署。

3.10 别重复自己

重复可能是软件中一切邪恶的根源。许多原则与实践规则都是为了控制与消除重复而创建的。

3.11 结构化编程

只要函数保持短小,偶尔出现的return、break或continue语句没有坏处,甚至比单入单出原则更具有表达力。

3.12 如何写出这样的函数

写代码和写别的东西很像。在写论文或文章时,你先想什么就写什么,然后再打磨它。初稿也许粗陋无序,你可以对其斟酌推敲,直至达到你心目中的样子。

3.13 小结

每个系统都是使用某种领域特定语言搭建的,而这种语言是程序员设计来描述那个系统的。

大师级程序员把系统当作故事来讲,而不是当作程序来写。

真正的目标在于讲述系统的故事,而你编写的函数必须干净利落地拼装到一起,形成一种精确而清晰的语言,帮助你讲故事。



Reading NotesClean Code Share Tweet +1