结构化设计的基本思想,就是把系统设计成由相对独立、功能单一的模块组成的层次结构。为了衡量模块的相对独立性,提出了模块间耦合(Coupling)与模块功能的内聚(Cohesion)这两个概念。它们从不同的侧面反映了模块的独立性。耦合反映模块之间连接的紧密程度,内聚反映模块内各元素彼此结合的紧密程度。如果所有模块的内聚都很强,模块之间的耦合自然就低,模块的独立性就强。反之亦然。
1.尽量降低模块间的耦合度
(1)耦合
耦合是影响系统复杂程度的一个重要因素。模块间的耦合度越低,模块的独立性就越高。例如,为了理解模块A,需要了解模块B,则A和B之间就有联系,需要对B的理解越多,其间的连接就越紧密,即耦合度越紧。程序员要修改紧耦合中的一个模块,很可能不得不修改另一个模块。可见,模块间的耦合程度对系统的可维护性、可靠性有强烈的影响。
(2)降低模块间耦合度的好处
·耦合度越低,模块间相互影响就越小,产生连锁反应的概率就越低;
·耦合度越低,可以使修改范围控制在最小限度;
·耦合度越低,一个模块修改时对系统其他部分正常运行的影响越小。
(3)影响模块间耦合度的因素
①联系方式:模块间通过什么方式联系。
②来往信息:模块间来往信息起哪些作用。
③数量:模块间来往信息的多少。
这三个因素共同作用,如图6-7所示,离坐标原点越近,耦合程度越低,性能越好。
图6-7 影响耦合的因素
(4)耦合的形式
①数据耦合(Data Coupling)
指两个模块之间的联系是通过数据交换而实现的。这是一种理想的耦合,由于模块与其他模块之间的联系是数据联系,这个模块就像一个黑箱,耦合度最低。如图6-8(a)所示的两个模块之间只传递了数据,耦合度低。
图6-8 模块耦合度
②控制耦合(Control Coupling)
两个模块之间除了传递数据信息外,还传递控制信息。控制耦合的不足有:一,需要理解开关量;二,记录具体开关量的取值。如图6-8(b)所示的两个模块之间,不仅传递了数据,还传递了控制信息,耦合度较高。A模块需要理解开关量并记住开关值是“平均”还是“最高”,以便数据从被调用模块返回后作相应处理。控制耦合是可以避免的,如本例,只要将被调模块分解成“取平均成绩”和“取最高成绩”两个,将主控模块改为条件调用即可。
③公共环境耦合(Common Environment Coupling)
当两个或多个模块通过一个公共数据环境相互作用时,它们之间的耦合称为公共环境耦合。公共环境耦合中共用的可以是全程变量内存的公共覆盖区任何存储介质上的文件。如图6-8(c)所示,模块A、B、C、D共用公共数据区内的元素,C、D之间没有关系,但存在着公共耦合。
④内容耦合(Content Coupling)
一个模块与另一个模块的内部属性(程序或内部数据)直接发生联系,又称为非法耦合。内容耦合的两个模块间是病态联结,在修改其中一个模块时,将直接影响到另一个模块,产生波动现象,影响整个系统。因此,在系统设计时,应完全避免内容耦合。其具体表现有:
·一个模块访问另一个模块内部的数据。
·一个模块调用另一个模块中间的部分程序代码。
·模块的出入口不符合单入单出的原则。
(5)各种耦合形式的耦合度比较(www.xing528.com)
综上所述,将各种耦合形式的耦合程度进行比较,如表6-1所示。
表6-1 各类耦合度的比较
2.尽量提高模块内的聚合度
模块的内聚反映模块内部联系的紧密程度。如果一个模块内部相关性很高,都是为了实现同一个功能,我们就说它的内聚程度很高。模块的内聚度越高,其独立性越好。模块的内聚有七种形式。按内聚度由低到高排列如下:
(1)偶然内聚(Coincidental Cohesion)
又称为机械内聚。如果一个模块的构成是由若干个毫无关系的功能偶然组合在一起的,则称该种内聚为偶然内聚,其内聚度最低,可修改性最差。
例如,当设计A、B、C时发现有相同的部分a,则把a抽出作为一个模块。如图6-9(a)所示,a只是若干条无关语句的简单拼凑,其本身与系统的数据流、控制流无关,a内部的紧密程度等于零,无法将其作为一个独立的模块去理解。
图6-9 模块内聚度
(2)逻辑内聚(Logical Cohesion)
如果一个模块内部各个组成部分的处理功能彼此无关,但处理逻辑相似,则称该种内聚为逻辑内聚。
例如:“录入”模块包括 “合同数据录入”、“客户数据录入”、“产品数据录入”等,从逻辑上讲它们是类似的功能。“录入”模块则为逻辑内聚的模块。
逻辑内聚的不足,一是调用该模块时,必须完全知道模块内部的属性;二是该模块与其他模块耦合度高,修改性差,维护困难。
(3)时间内聚(Temporal Cohesion)
又称暂时内聚。如果一个模块内各个组成部分的处理功能和时间有关,则称该种内聚为时间内聚。例如,初始化模块是典型的时间聚合模块。时间内聚的内聚度比前两种稍高一些,但它们都属于低程度的内聚,在设计时应尽量避免使用。
(4)步骤内聚(Procedural Cohesion)
又称为过程内聚。如果一个模块内部各个组成部分的处理功能各不相同,彼此也没有数据关系,但它们都受同一个控制流支配,决定它们的执行次序,也就是说模块内的元素属于同一个公共步骤单元,则该种聚合为步骤内聚。这种内聚的内聚程度高于时间内聚,但往往导致模块间耦合度高。
(5)通信内聚(Communicational Cohesion)
又称数据内聚。指模块内的部分组成部分处理功能,都使用相同的输入数据或产生相同的输出数据,且其中各个处理功能是无序的。如图6-9(b)所示。
(6)顺序内聚(Sequential Cohesion)
如果一个模块内部各个组成部分执行几个处理功能,且前一个处理功能所产生的输出数据直接成为后一个处理功能的输入数据,则该种聚合为顺序聚合。如图6-9(c)所示。
与通信内聚相比,顺序内聚的内聚程度更高,因为不论从数据的角度还是从执行的顺序来看,模块内各成分的关系都更紧密。
(7)功能内聚(Functional Cohesion)
如果一个模块内部的各个组成部分的处理功能全部为执行同一个功能而存在,并且只执行一个功能,则称这种内聚方式为功能内聚。功能内聚模块的优点在于界面清晰,容易理解,由于一个模块一个功能,因而复用性好。功能内聚的聚合度最高,是系统设计的目标。
判断一个模块是否为功能内聚的办法是:从调用者的角度看,用一个短语简单明确地描述这个模块做什么,分析这个短语,判断模块是完成一个具体任务,还是多个任务,如果是完成一个具体任务,则这个模块是功能内聚的。
3.模块的扇出系数和扇入系数
模块的扇出系数指一个模块拥有的直属下层模块的个数,一般认为,设计得好的系统平均扇出数为3或4,上限不超过7。一个模块的扇出数过大意味着管理模块过于复杂,需要控制和协调过多的下级,可以通过增加中间层次减小其扇出数。
一个模块的扇入是指调用它的上级模块的个数。扇入越大,模块共享度越高,这当然是我们所希望的,但是不能为了获得高扇入牺牲其他的属性。例如把彼此无关的功能凑在一起构成一个模块,虽然扇入数高了,但内聚度则必然下降。
设计得好的系统,上层模块有较高的扇出,下层模块有较高的扇入,其结构图呈现出上尖、中宽、下小的特点。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。