干净的代码: 编写可读的函数


以下是 Clean Code 关于编写可读函数的建议的摘要。
这个建议是针对用 OOP 语言编写的函数,尽管许多概念会延续到其他编程范式。
 
原则 1 - 小!

  • 你的大部分功能应该少于15行,而且几乎不应该超过20行。
  • 你应该总是能够把整个函数放在你的显示器上。如果你不能,那么你可能需要将该函数分解成不同的函数。
  • 如果你遵循这个原则,就意味着你的函数不会大到可以容纳几个嵌套结构。你将无法装下一个循环,然后在这个循环里面装下一个嵌套的if/else语句,等等。
  • 相反,你应该让这些嵌套结构成为独立的函数调用。这也增加了文档的价值,因为这些函数会有很好的描述性的名字来解释它们做什么。

 
原则 2 - 做一件事
  • 另一种陈述原则1的方式是,你的函数应该只做一件事。
  • 一个好的启发式方法是看你是否能从你的函数中提取一些代码,并将这些代码变成一个新的函数,其名称不仅仅是对其实现的重述。
  • 如果你能做到这一点,那就表明你的函数在做多件事情,你应该进一步将其分解。

  
原则 3 - 每个函数的一个抽象级别
  • 你的程序经常可以被划分为不同的抽象层,每一层都代表相同信息和过程的不同模型,但方式不同。
    一个例子是,如果你正在开发一个程序来刮取一个网站,解析一些数据,然后把这些数据放到一个数据库中。
    一个抽象层是你向网站的服务器发送HTTP请求后得到的HTML字符串。
  • 你把这个HTML字符串发送到你的第二层抽象,在那里,一个HTML解析器把这个字符串转换成一个对象,其中HTML页面被表示为一个嵌套的数据结构(如果你想要一个更具体的例子,请阅读BeautifulSoup)。这是第二层的抽象。
  • 第三层抽象可以是你从HTML页面对象中提取你需要的特定数据,并将这些数据存储在一个数组中。
  • 第四层抽象是将数组中的数据写入数据库。

 一个函数中的语句应该都在同一个抽象层次上。

你不应该在同一个函数中操作HTML字符串对象和写入数据库。

相反,"清洁代码 "建议采用 "下降法则"(The Stepdown Rule),即你的代码可以作为一个自上而下的叙事来阅读。

每个函数后面都应该有一个下一层抽象的函数。这样一来,当你阅读程序时,你就会在通过函数列表时,每次都会下降一层抽象概念。
 
原则 4 - 使用描述性名称
如果你遵循前三个原则,那么想出一个名字应该不会太难。

你的功能越小、越集中,就越容易想出一个名字。

不要害怕让你的名字变长。一个长的、描述性的名字比一个短的、模糊的名字要好得多。你的编辑器的自动完成功能应该使你很容易写出带有长函数名称的代码。

另外,使用一种命名惯例,允许在函数名中轻松读出多个单词。CamelCase就是一个例子。

 
原则 5 - 使用更少的函数参数
一个函数的理想参数数是零。应该避免一个函数有三个以上的参数。

有很多函数参数会使你更难阅读和理解函数,因为它迫使你知道额外的细节(而这些细节通常来自不同的抽象层)。

此外,有很多函数参数会使你更难编写测试。你必须写出所有的测试用例,以确保所有不同的参数组合都能正常工作!你必须写出所有的参数。

 
原则 6 - 避免副作用
副作用是您的函数在其本地环境之外修改某些状态变量的地方,除了返回一个值(预期效果)。
一个示例可能是从数据库中读取某个值然后返回该值的函数。
如果同一个函数也以某种方式修改状态(并且该修改在函数终止后持续),那么该修改是一个副作用。
Clean Code 建议您避免副作用。
你的函数要么改变对象的状态,要么返回一些信息。一个函数不应该两者兼得!
 
原则 7 - 使用异常,而不是错误代码
您的函数应该很少返回错误代码。相反,如果出现问题,您应该抛出异常,并提供编写良好的错误消息。
错误代码的一个问题是它会导致深度嵌套的结构。当您返回错误代码时,调用者必须立即处理该错误代码。
另一方面,调用者可以将异常处理程序逻辑与其他代码分开(try、catch 语句具有单独的 try 逻辑和 catch 逻辑)。