块间联系的度量—耦合度

耦合度是从模块外部考察模块的独立性程度。它用来衡量多个模块间的相互联系。一般来说,耦合度应从以下三方面来考虑,即:

耦合内容的数量,即模块间发生联系的数据和代码的多少,同这些数据和代码发生联系的模块的多少,多的耦合强,少的耦合弱;

模块的调用方式,即模块间代码的共享方式。可分为用 CALL 语句调用方式和用 GOTO 语句直接访问方式;

模块间的耦合类型。耦合类型有以下几种方式:

①独立耦合

②数据耦合

③控制耦合

④公共耦合

⑤内容耦合

下面重点对各种类型的耦合作进一步的说明。

  1. 独立耦合

指两个模块彼此完全独立,没有直接联系。它们之间的唯一联系仅仅在于它们同属于一个软件系统或同有一个上层模块。这是耦合程度最低的一种。当然,系统中只可能有一部分模块属此种联系,因为一个程序系统中不可能所有的模块都完全没有联系。

  1. 数据耦合

指两个模块彼此交换数据。如一个模块的输出数据是另一个模块的输入数据,或一个模块带参数调用另一个模块,下层模块又返回参数。应该说, 在一个软件系统中,此种耦合是不可避免的,且有其积极意义。因为任何功能的实现都离不开数据的产生、表示和传递。数据耦合的联系程度也较低。

  1. 控制耦合

若在调用过程中,两个模块间传递的不是数据参数而是控制参数,则模块间的关系即为控制耦合。控制耦合属于中等程度的耦合,较之数据耦合模块间的联系更为紧密。但控制耦合不是一种必须存在的耦合。

当被调用模块接收到控制信息作为输入参数时,说明该模块内部存在多个并列的逻辑路径,即有多个功能。控制变量用以从多个功能中选择所要执行的部分,因而控制耦合是完全可以避免的。排除控制耦合可按如下步骤进行:

①找出模块调用时所用的一个或多个控制变量;

②在被调模块中根据控制变量找出所有的流程;

③将每一个流程分解为一个独立的模块;

④将原被调模块中的流程选择部分移到上层模块,变为调用判断。

通过以上变换,可以将控制耦合变为数据耦合。由于控制耦合增加了设计和理解的复杂程度,因此在模块设计时要尽量避免使用。当然,如果模块内每一个控制流程规模相对较小,彼此共性较多,使用控制耦合还是合算的。

  1. 公共耦合

公共耦合又称公共环境耦合或数据区耦合。若多个模块对同一个数据区进行存取操作,它们之间的关系称为公共耦合。公共数据区可以是全程变量、共享的数据区、内存的公共复盖区、外存上的文件、物理设备等。当两个模块共享的数据很多,通过参数传递可能不方便时,可以使用公共耦合。公共耦合共享数据区的模块越多,数据区的规模越大,则耦合程度越强。公共耦合最弱的一种形式是:两个模块共享一个数据变量,一个模块只向里写数据, 另一个模块只从里读数据。

当公共耦合程度很强时,会造成关系错综复杂,难以控制,错误传递机会增加,系统可靠性降低,可理解、维护性差。

  1. 内容耦合

内容耦合是耦合程序最高的一种形式。若一个模块直接访问另一模块的内部代码或数据,即出现内容耦合。内容耦合的存在严重破坏了模块的独立性和系统的结构化,代码互相纠缠,运行错综复杂,程序的静态结构和动态结构很不一致,其恶劣结果往往不可预测。

内容耦合往往表现为以下几种形式:

①一个模块访问另一模块的内部代码或数据;

②一个模块不通过正常入口而转到另一个模块的内部(如使用 GOTO 语句或 JMP 指令直接进入另一模块内部);

③两个模块有一部分代码重迭(可能出现在汇编程序中,在一些非结构化的高级语言,如 COBOL 中也可能出现);

④一个模块有多个入口(这意味着一个模块有多种功能)。

一般讲,在模块划分时,应当尽量使用数据耦合。少用控制耦合(尽量转成数据耦合),限制公共耦合的范围,完全不用内容耦合。