块内联系的度量——内聚度

内聚度(Cohesion)是模块内部各成份(语句或语句段)之间的联系。显然,模块内部各成份联系越紧,即其内聚度越大,模块独立性就越强,系统越易理解和维护。具有良好内聚度的模块应能较好地满足信息局部化的原则,功能完整单一。同时,模块的高内聚度必然导致模块的低耦合度。理想的情况是:一个模块只使用局部数据变量,完成一个功能。

按由弱到强的顺序,模块的内聚度可分为以下 7 类,现分述于下。

  1. 偶然内聚

块内的各个任务(通过语句或指令来实现的)没有什么有意义的联系, 它们之所以能构成一个模块完全是偶然的原因。如下图 3-4-1 所示。

在模块 T 有三条语句。至少从表面上看不出这三条语句之间有什么联系,只是由于 P,Q,R,S 四个模块中都有这三条语句,为了节省空间才把它们作为一个模块放在一起。这完全是偶然性的。偶然内聚的模块有很多缺点:

块内联系的度量——内聚度 - 图1由于模块内

没有实质性的联系,很可能在某种情况下一个调用模块需要对它修改而别的模块不需要。这时就很难处理。同时,这种模块的含义也不易理解,甚至难以为它取一个合适的名字,偶然内聚的模块也难于测试。所以,在空间允许的情况下,不应使用这种模块。

  1. 逻辑内聚

块内联系的度量——内聚度 - 图2一个模块完成的任务在逻辑上属于相同或相似的一类(例如,用一个模块产生各种类型的输出),则该种模块内的联系称为逻辑内聚。如图 3-4-2a 和 3-2-2b 所示。

在图 3-4-2a 中,模块 A,B,C 的功能相似但不相同,如果把它们合并成一个模块 ABC,如图 3-4-2b 所示,则这个模块就为逻辑内聚,因为它们是由于逻辑上相似而发生联系的。逻辑内聚是一种较弱的联系。实际执行时,当X,Y,Z 调用合成的模块 ABC 时,由于原 A,B,C 并不完全相同,所以还要判别是执行不同功能的哪一部分。

块内联系的度量——内聚度 - 图3

逻辑内聚存在的问题是:

①修改困难,调用模块中有一个要对其改动,还要考虑到其它调用模块;

②模块内需要增加开关,以判别是谁调用,因而增加了块间联系;

③实际上每次调用只执行模块中的一部分,而其它部分也一同被装入内存,因而效率不高。

  1. 时间内聚

时间内聚是指一个模块中包含的任务需要在同一时间内执行(如初始化,结束等所需操作)。如图 3—4—3 所示的模块。与偶然内聚和逻辑内聚相比,这种内聚类型要稍强些,因为至少在时间上,这些任务可以一起完成。但时间内聚和偶然内聚、逻辑内聚一样,都属低内聚度类型。

  1. 过程内聚

如果一个模块内的各个处理元素是相关的,而且必须按固定的次序执行,这种内聚就叫做过程内聚。过程内聚的各模块内往往体现为有次序的流程。如图 3-4-4 所示的处理模块。

块内联系的度量——内聚度 - 图4

  1. 通信内聚

若一个模块中的各处理元素需引用共同的数据(同一数据项、数据区或文件),则称其元素间的联系为通信内聚。通信内聚的各部分间是借助共同使用的数据联系在一起的,故有较好的可理解性。如图 3—4—5 所示。通信内聚和过程内聚都属中内聚度型模块。

  1. 顺序内聚

若一个模块内的各处理元素关系密切,必须按规定的处理次序顺序执行,这样的模块为顺序内聚类型。顺序内聚的模块内,后执行的语句或语句段往往依赖先执行的语句或语句段,以先执行的部分为条件。由于模块内各处理元素间存在着这种逻辑联系,所以顺序内聚模块的可理解性很强,属高内聚度类型模块。如图 3-4-6 所示的例子。

块内联系的度量——内聚度 - 图5

  1. 功能内聚

功能内聚是内聚度最高的一种模块类型。如果模块仅完成一个单一的功能,且该模块的所有部分是实现这一功能所必须的,没有多余的语句,则该模块为功能内聚。功能内聚模块的结构紧凑、界面清晰,易于理解和维护,因而可靠性强;又由于其功能单一,故复用率高。所以它是模块划分时应注意追求的一种模块类型。如图 3—4—7 是模块划分时得到的功能内聚模块。在模块设计时应力争做到高内聚,并且能够辨别出低内聚的模块,加以

修改使之提高内聚度并降低模块间的耦合度。具体设计时,应注意:

①设计功能独立单一的模块;

②控制使用全局数据;

③模块间尽量传递数据型信息。