代码整洁之道

本文为《代码整洁之道(Clean Code)》一书的读书笔记。这本书是以Java开发为例,但一些基本的原则是通用的。

书中以Java为例,从命名、函数、类、注释、单元测试、格式、错误处理并发编程等各方面详细介绍了如何让代码变得整洁。整洁的代码有很多特征,其中最重要的,也是一眼能够看出来的,就是整洁的代码都是短小的。诚然短小的代码并不一定都整洁,但整洁的代码一定是短小的,它每份文件的代码量是短小的,每个类是短小的,每个函数是短小的,每个注释是短小的,每个单元测试同样也是短小的。

短小就意味着代码没有多余的内容,意味着代码结构清晰,意味着更好的可读性。

当然短小是有前提的,就是所有的代码命名都是有意义的,类名、函数名、变量名都是有意义的,要在有意义的前提下,尽量做到短小。

有意义的命名

一个有意义的命名有以下特点:

  • 名副其实
  • 避免误导
  • 做有意义的区分,比如同样两只狗,不能叫dog1、dog2这样无意义的区分,可以叫smallDog、bigDog这种有意义。
  • 使用读得出来的名称
  • 使用可搜索的名称
  • 每个概念对应一个词
  • 添加有意义的语境,避免添加无用的语境

类应该短小

关于类的第一条规则是类应该短小。第二条规则是还要更短小。

单一职责原则(SRP:Single responsibility principle)

要想类变得短小,首先类不能拥有太多权责,而应该遵循单一权责原则。职责是指类变化的原因,单一职责原则就是指一个类应该有且只有一个修改的原因。

遵循单一职责原则的类,它拥有的属性和方法会比多职责类要少。这是让类变得短小的根本方法。

系统应该由许多短小的类而不是少量巨大的类组成。每个小类封装了一个职责,只有一个修改的原因,并与少数其他类一起协同达成期望的系统行为。

高内聚性

内聚是指一个模块内部各成员之间相互关联的程度。高内聚性,则意味着类内部的各个成员互相依赖、互相聚合的程度高。如果一个类中每个变量都被每个方法所使用,说明这个类具有最大的内聚性。

一个类应该是高内聚、低耦合的。内部互相依赖,结合一个整体,外部不会有依赖关系。当类的某个实体变量只被少数方法使用,则意味着这个类正在丧失内聚性,应该考虑对其进行拆分了。因此保持类的高内聚性,会得到许多短小的类。

函数应该短小

和类一样,函数的第一规则是短小,第二规则是还要更短小。

只做一件事件

和类一样,要让函数短小,根本方法是要让一个函数只做一件事件。

每个函数一个抽象层级

要确保函数只做一件事,函数中的语句应该都在同一抽象层级上。我感觉这是做到函数整洁的一个很重要的规则。一个函数内部如果混杂着不同层级的代码,往往会导致代码的混乱,不同层级的代码在函数中纠缠。

无副作用

副作用是一种谎言。函数只承诺做一件事,但往往在内部会对类的变量做一些改动。这很容易导致内部一些函数调用的顺序依赖,造成必须按某种特定的顺序调用函数,换一种顺序就会出现bug。

此外,函数还应该使用描述性的名称,宁愿让名称长一点,也要将函数所做的事描述清楚。另外,函数参数应该越少越好。

注释要短小

最好的注释是没有注释

只有在我们无法用代码表达意图时才需要注释,注释很多时候是为了弥补失败的代码。注释会撒谎,而代码永远是真实的,我们应该尽量让代码来表达一切。除了提供代码之外的信息需要注释外,其它的注释都应该避免。

代码之外的信息包括:

  • 法律信息
  • 对代码意图的解释
  • 警示
  • TODO注释

单元测试的短小

单元测试要保持短小,最根本的方法是遵循TDD的三定律:

  • 在编写不能通过的单元测试前,不可编写生产代码。
  • 只编写刚好无法通过的单元测试,编译错误也算不通过。
  • 只可编写刚好足以通过当前失败测试的生产代码。

遵循了这三条规则,我们所写的所有测试代码都是刚好能够导致测试无法通过的代码,没有重复的测试代码。

此外,和每个函数只做一件事一样,每个测试函数也应该只测试一个测试条件。

坚持原创技术分享,您的支持将鼓励我继续创作!