高内聚和低耦合一直是面向对象设计后面隐藏的两个设计核心原则,那么内聚与耦合到底是个什么概念呢?
1、内聚高内聚表示某个特定的软件模块——无论是一个子程序、一个类型还是一个类库,都应该完成一系列极为相关的功能。换句话说,内聚表示同一个类型中不同方法、同一个类库中的不同函数或者同一个方法中的不同操作所表达的逻辑之间的距离。
若你查看一下内聚在化学领域中的定义,定会更加清楚地理解软件中内聚的含义。在化学界中,内聚是物质的一种物料属性,表示物体中分子之间的吸引能力。
内聚的衡量标准是从低到高,内聚越高说明软件设计得越好。高内聚的模块意味着高的可维护性和可重用性,因为这些模块的外部依赖很少。低内聚则让人难以理解类型的设计意图,容易导致出现坚硬,易碎的软件。低内聚的模块也会在各个模块中留下很多依赖,让设计变的顽固且高粘度(坚硬,易碎的软件,高粘度等问题请查看本站:
三个暗示你的架构设计开始走下坡路的信号)。
代内聚的设计会使模块(如类型)的职责(如方法)彼此关系松散,甚至是在完成一些毫不相关的操作。在实际中,高内聚原则建议我们创建尽可能专门的类型,包含较少的方法,用来完成逻辑上相关的操作。若方法之间的逻辑距离有所增加,那么应该拆分成另外的类型。
Ward Cunningham(一位根限编程的先驱)为内聚给出了一个简捷实用的定义。在他看来,
如果修改了模块A,且不会影响到模块B,那么A和B两个模块就有了足够的内聚,值得在系统中使用。
还有一句话,同样来自Ward Cunningham,可用来巩固前面提到的内聚概念。Ward Cunningham建议,模块(如一个类型)的内聚高低与其担当的职责多少成反比关系。我们对此深表赞同。
与内聚紧密相关的是单一职责原则(Single Responsibility Principle,SRP)。请大家自已查找单一职责原则概念。
2、耦合耦合是用来度量两个软件模块,例如,类型,函数或类库之间的依赖程度。耦合的一个非常精彩的描述同样来自Ward Cunningham:
若每次修改模块A时都要修改模块B,那么A和B这两个模块就是耦合的。
换句话说,虽然模块B没有直接或逻辑上与模块A的修改相关,但因为二者之间存在依赖,所以B不得不随之调整,否则代码将无法编译。
耦合的衡量标准从低到高,耦合越低说明软件设计得越好。低耦合并不是说你的模块应该与其他模块完全隔绝。模块之间显然需要通信,不过通信应该依赖于一系列设计良好且不易改变的
接口。每个模块都应该在无需了解另一个模块内部实现细节的情况下与之良好配合。
相反地,高耦合会阻碍测试过程、降低代码重用性并影响代码的理解。高耦合也是导致坚硬、易碎软件的一个主要原因。
低耦合和高内聚唇齿相依。若系统满足了这两个条件,那么通常来说该系统已经满足了高可读性,高可维护性,易于测试和易于重用的要求。
低耦合和高内聚最初是用来指导结构化设计的,因此它并不仅仅适用于面向对象设计中。不过即使在面向对象场景中,二都也有着非常重要的位置。一个好的面向对象设计同样需要满足低耦合和高内聚的原则,即功能完备的对象(高内聚)之间通过固定的接口进行交互(低耦合)。
一个有助于实现低耦合和高内聚的原则是分离关注点(Separation of Concerns,SoC),大家可以关注本站的下一篇文章。