本文为敏捷软件开发 - 原则、模式与实践系列的一部分。
本文对应原书第20章后半部分
包的耦合性原则
无环依赖原则(ADP - The Acyclic Dependencies Principle )
在包的依赖关系图中不允许存在环。
解除依赖环的方法
- 使用依赖倒置原则。
- 创建一个新包,把共同依赖的类移动到新包里面。
稳定依赖原则(SDP - The Stable-Dependencies Principle )
朝着稳定的方向进行依赖
稳定性和更改所需要的工作量有关。
包稳定性度量
一种方式是计算进、出该包的依赖关系的数目。我们可以使用这些来数值计算该包的位置稳定性。
-
Ca
输入耦合度:指处于该包的外部并依赖于该包内的类的类的数目。 -
Ce
输出耦合度:指处于该包的内部并依赖于该包外的类的类的数目。 - 不稳定性
I
:I = Ce / (Ca + Ce)
该度量的取值范围是[0, 1]。
当一个包的I
度量值为1时,就意味着没有任何其他的包依赖于该包(Ca=0
),而该包依赖于其他的包(Ce > 0
)。这是一个包最不稳定的状态;它是不承担责任并且有依赖性的。因为没有包依赖于它,所以它就没有不改变理由,而它所依赖的包会给它提供丰富的更改理由。
另一方面,当一个包的I
度量值为0时,就意味着其他包会依赖于该包(Ca > 0
),但是该包却不依赖于任何其他的包(Ce=0
)。它是负有责任且无依赖性的。这种包达到了最大程度的稳定性。它的依赖者使其难以更改,而且没有任何依赖关系会迫使它去改变。
SDP规定一个包的I
度量值应该大于它所依赖的包的I度量值(也就是说,I
度量值应该顺着依赖的方向减少)。
如果一个系统中所有的包都是最大程度稳定的,那么该系统就是不能改变的。这不是希望的情形。事实上,我们希望所设计出来的包结构中,一些包是不稳定的而另一个包是稳定的。
可改变的包位于顶部并依赖于底部稳定的包。把不稳定的包放在图的顶部是一个有用的约定,因为任何向上的箭头都意味着违反了SDP。
稳定抽象原则(The Stable-Abstractions Principle)
包的抽象程度应该和其稳定程序一致
该原则把包的稳定性和抽象性联系起来。它规定,一个稳定的包应该也是抽象的,这样它的稳定性就不会使其无法扩展。另一方面,它规定,一个不稳定的包应该是具体的,因为它的不稳定性使其内部的具体代码易于更改。
SAP和SDP结合在一起形成了针对包的DIP原则。这样说是准确的,因为SDP规定依赖应该朝着稳定的方向进行,而SAP则规定稳定性意味着抽象性。因为,依赖应该朝着抽象的方向进行。
包抽象度度量
A
是一个测量包抽象程度的度量标准。它的值就是包中抽象类的数目和全部类的数目的比值。
-
Nc
- 包中类的总数 -
Na
- 包中抽象类的数目 -
A = Na / Nc
- 包的抽象性
度量A
的取值范围是从0到1。0意味着包中没有任何抽象类。1意味着包中只包含抽象类。
自下而上设计包
包结构应该是随着系统的增长、变化而逐步演化的。
事实上,包的依赖关系图和描绘应用程序的功能之间几乎没有关系。相反,它们是应用程序可构建性的映射图。这就是为何不在项目开始时设计它们的原因。在项目开始时,没有软件可构建,因此也无需构建映射图。但是,随着实现和设计初期累积的类越来越多,对依赖关系进行管理,避免项目开发中出现循环依赖的需求就不断增长。此外,我们也想尽可能地保持更改的局部化,所以我们开始关注SRP和CCP,并把可能会一同变化的类放在一起。
随着应用程序的不断增长,我们开始关注创建可重用的元素。于是,就开始使用CRP来指导包的组合。最后,当环出现时,就会使用ADP,从而包的依赖关系图会出现抖动以及增长。
完整内容请查看敏捷软件开发 - 原则、模式与实践系列