《软件架构基础》系列是对Mark Richards 和 Neal Ford编写的 Fundamentals of Software Architecture 的读书总结, 本文总结了模块化(Modularity)。
目录
传入耦合(Afferent Coupling)与传出耦合(Efferent Coupling)
抽象度与不稳定性的平衡关系——主序列距离(Distance from the Main Sequence)
定义
模块(Module)指相互关联代码构成的逻辑组。在面向对象语言中模块可以是一组类,在结构化语言中模块可以是一组函数。
在架构领域中,模块化(modularity)就是表示从逻辑上给相互关联的代码分组的过程。
模块化的度量
为了度量模块化的优劣,可以使用三个度量指标:内聚,耦合和共生。
内聚(Cohesion)
内聚度量了模块的组成部分间相互关联的程度。理想中的内聚模块是有由一系列部分构成的整体,在这个整体中如果分割出更小的部分出来(作为单独的模块),则需要耦合(coupling)它们来实现有意义的结果。
逻辑化内聚度量
从逻辑角度度量,内聚从优到劣可以分为以下几种:
- 功能内聚(Functional cohesion)
- 模块的每个部分彼此相关,并且模块的每个部分都是完成某个功能所必须的(复杂数据依赖,依赖成不规则的网状,难以解耦)。
- 顺序内聚(Sequential cohesion)
- 模块的每个部分与一个功能相关,且各部分间存在顺序关系,一个部分的输出作为另一个部分的输入。(类似于pipe & filter,顺序数据依赖,依赖形成线性关系)
- 通信内聚(Communicational cohesion)
- 模块的所有部分形成通信链,操作或者生成统一数据集。所有部分依赖于同一个数据结构。 (共同数据依赖形成的内聚,总线型或星型依赖)
- 过程内聚(Procedural cohesion)
- 模块中的每个部分需要按一定的步骤(过程)的次序执行。(执行前后顺序,区别于顺序内聚的数据强相关性,)
- 时间内聚(Temporal cohesion)
- 模块中的每个部分是依赖于时间相互关联的,如需要在同一时间执行。(时间依赖)
- 逻辑内聚(Logical cohesion)
- 模块中的每个部分是逻辑相关的而不是功能相关的。如通用的字符串处理模块。(逻辑关联型依赖)
- 巧合内聚(Coincidental cohesion)
- 模块中的每个部分没有关联,只是巧合地出现在同一个代码组里。
相比于耦合,内聚是一个较不准确的度量,从逻辑角度判断内聚的高低在很多时候存在主观性。在回答哪一种模块化方式内聚性更优的时候,需要具体问题具体分析。
结构化内聚度量 LCOM
尽管内聚指标难以客观地进行逻辑度量,计算机科学家仍然提出了结构化的内聚度量方法。Chidameter 和 Kemerer 提出了一种LCOM方法 (Lack of Cohesion in Methods) 用于度量模块特别是组件的内聚。
LCOM方法利用公式计算一个度量模块缺乏内聚程度的值。
早期的版本LCOM公式为:
P和Q度量了方法对属性的共享情况。计算方法为:取类中任意一对方法,如果他们没有共同访问任何属性,P加1;反之,如果他们共同访问至少一个属性,Q加1。
而1996年更新的版本LCOM公式为: