《Effective Unit Testing》 读书笔记 9 具有可测性的设计

具有可测性的设计,不是说代码设计得能不能被测试,而是说代码能不能被容易得写出测试。可测性设计中最重要的一个设计经验,也是软件开发中最基本的一个设计原则,就是模块化。模块化让不同部分的代码的耦合度降低,功能的内聚增高,使其容易被替换,容易被测试。

模块化说起来过于抽象。所以产生了一些比较具体的设计原则。其中很有名的就是用于OO设计中的SOLID原则,有必要在这里复习一下。我个人觉得这几个原则可以通过死记硬背来记忆,不过在概念上为什么是这个五个并不太清晰,几条原则中间没有太大逻辑性。(OO中类似还有个GRASP原则)

S代表Single Responsibility Principle (SRP) 单一功能原则。这个原则分为两个方面,从外部看,一个方法只有一个职责,干了一件事情,这个很容易理解。但是实际开发中,我们还需要相对的一种内部视角,表述起来可能比较拗口:“一个类需要被修改的原因只能有一个”。啥叫原因只有一个?这和方法和对象的抽象层次就很有关系。具体说来可以另写一篇文章。功能高度单一的类容易被测试,这是很显然的。

O代表Open Closed Principle(OCP) 开闭原则。是说类对扩展开放,对修改关闭。听起来有点抽象。这条原则说的就是设计一个类的时候,在考虑未来的需求变动要对这个类的行为的改变的时候,要能通过扩展(也就是替换一部分)的方式进行,而不需要改变类的源代码。这就和如何使用测试替身的概念十分有关。开闭原则遵守得好的类,也容易通过测试替身扩展的方式进行测试。

L代表Liskov Substitution Principle(LSP)里氏替换原则。叫这个名字是因为这条原则是被计算机科学家Babara Liskov提出的。这条规则很简单,就是一个类的子类能替换它的基类(接口)。也就是说子类的行为必须符合基类定下的contract。那么对测试而言,类只要遵从这条规则,针对某基类或某接口写的测试就可以用于测试所有的子类和实现。

I代表Interface Segregation Principle(ISP)接口隔离原则。这条原则是说使用某个接口的Client不需要依赖接口中它使用不到的方法。也就是说设计接口的功能要单一。也有人说ISP就是对接口而言的SRP。单一功能的接口自然容易被测试。

D代表Dependency Inversion Principle(DIP)依赖反转原则。它说的是:高层模块不应该依赖于低层模块,它们都应该依赖于抽象。抽象不依赖于实现细节,而是实现细节依赖于抽象。这个问题要说清楚可能还是需要代码例子,这里就不细说了。具体说来和另一个原则很接近:就是我们要面向接口而不是具体实现来编程。符合依赖反转的代码中具体实现容易被替换,自然也就容易被测试。

这一节其实泛泛讲了好的模块化(OO)设计原则,符合模块化设计的代码容易测试。下面会讲问题的反面,一些具体的会影响测试性的代码设计。

你可能感兴趣的:(《Effective Unit Testing》 读书笔记 9 具有可测性的设计)