首页 百科知识 耦合与内聚

耦合与内聚

时间:2022-10-09 百科知识 版权反馈
【摘要】:耦合度高则模块之间的接口复杂,不利于后续的软件编码、测试、维护,松散耦合是一种好的设计。此耦合的耦合度最低,且软件中必包含该耦合。软件设计人员需要通过合理的模块分解,将其耦合度降低。公共环境耦合的耦合度已经非常高,且随耦合模块数量的增加而显著增加。顺序内聚仍属于高聚度,仅次于功能内聚,评分9分。通信内聚属于中等程度的内聚,仅次于顺序内聚,评分7分。

4.2.3 耦合与内聚

一、耦合

耦合的定义:它是衡量模块间联系紧密程度的度量。耦合度高则模块之间的接口复杂,不利于后续的软件编码、测试、维护,松散耦合是一种好的设计。因此,软件设计人员应该尽量设计松散耦合的软件系统。常见的耦合有下面几种:

1.非直接耦合

模块之间没有直接的调用关系,而是通过它们共同的父模块发生了非直接关系,则这些模块之间的耦合属于非直接耦合。此耦合的耦合度最低,且软件中必包含该耦合。

如下图的某软件的软件结构中,(A、B、C)这组模块彼此之间未发生直接的模块调用关系,但它们却有一个共同的父模块“主模块”,因此,它们之间是一种非直接耦合关系,类似的还有(E、F、G)和(U、V、W)这两组模块。

img41

图4.6 非直接耦合的例子

2.数据耦合

模块之间存在直接的模块调用关系,且模块间通过传递简单参数(不是控制参数、公共数据结构或外部变量)发生关系,实现相关功能,则这些模块之间的耦合是数据耦合。此耦合的耦合度较低。软件系统中也必包含该耦合。

在下图的软件结构中,“开发票”模块和“计算水费”模块发生了直接的调用关系,且通过传递简单参数“单价”和“数量”完成这种调用关系,故这两个模块间就发生了数据耦合。

img42

图4.7 数据耦合的例子

3.特征耦合

模块之间通过参数传递复杂数据结构而发生调用关系,则这些模块间的耦合是特征耦合。例如模块间通过传递数据库记录、数组结构元素、链表结构元素等数据,则它们之间的耦合已不是简单的数据耦合,而是特征耦合。故特征耦合的耦合度较数据耦合高。特征耦合有时也称为标记耦合。

在下图的软件结构中,“计算水电费”模块和“计算水费”模块、“计算水电费”模块和“计算电费”模块均是通过在模块间传递“住户情况”数据完成了调用关系,由于“住户情况”是数据库表中的一条数据记录,故“计算水电费”和“计算水费”之间以及“计算水电费”和“计算电费”之间的耦合关系变得复杂,是一种特征耦合。

img43

图4.8 特征耦合的例子

4.控制耦合

模块之间通过传递控制参数发生调用关系,则模块间的耦合属于控制耦合。控制耦合高于特征耦合,已属于中等程度的耦合。该耦合增加了模块之间的依赖性,也使系统变得很复杂。软件设计人员需要通过合理的模块分解,将其耦合度降低。

在下图的软件结构中,A模块和B模块通过传递控制参数“平均分或最高分”发生了调用关系。当该参数传递到B模块中后,B模块根据它的值来选择执行“计算平均分”或“计算最高分”模块,因此,A模块和B模块间发生了控制耦合。作为被调用模块B,其对父模块A的依赖程度要远远高于数据耦合和特征耦合。

img44

图4.9 控制耦合的例子

5.公共环境耦合

模块之间通过一个公共数据环境(全局变量、共享的通信区、内存的公共覆盖区等)相互作用时,则它们之间属于公共环境耦合。公共环境耦合的耦合度已经非常高,且随耦合模块数量的增加而显著增加。

若只有两个模块发生了公共环境耦合,则公共环境耦合又可分为:

(1)松散公共环境耦合:一个模块向公共环境传送数据,另一个模块仅从公共环境中获取数据,它属于一种数据耦合,耦合度较低。

(2)紧密公共环境耦合:两个模块都既向公共环境传送数据,又从其中获取数据,则这是一种比较紧密的耦合,其耦合度介于数据耦合和控制耦合之间。

如下图所示,A模块和B模块通过一个公共数据区相互作用,它们之间是公共环境耦合。(a)图中A模块仅向公共数据区传送数据,而B模块仅从公共数据区获取数据,故它们之间是一种松散的公共环境耦合。而(b)图中A模块和B模块都既向公共数据区传送数据,又从公共数据区获取数据,彼此之间的联系非常紧密,是一种紧密的公共环境耦合。

img45

图4.10 公共耦合的例子

6.内容耦合

如果两个模块之间出现下面的情况之一,则发生了内容耦合:

(1)一个模块访问另一个模块的内部数据。

(2)一个模块通过非正常入口进入另一个模块内部。

(3)两个模块有部分代码重叠(一般在汇编语言中)。

(4)一个模块有多个入口。

内容耦合的耦合度相当高,应该坚决避免。

对于模块间的耦合可遵循如下原则进行优化设计:非直接耦合必然存在,数据耦合尽可能多使用,控制耦合和特征耦合少用,限制公共环境耦合的应用范围,完全不用内容耦合。

二、内聚

内聚的定义:它是衡量模块内部各个组成部分彼此联系紧密程度的度量。内聚高则模块内部联系紧密,模块的信息隐蔽和局部化设计好,模块的每一部分都是为实现一个特定的功能而结合在一起的,高内聚是一种好的设计。常见的内聚有下面几种:

1.功能内聚

模块内部所有元素都属于一个整体,它们组合在一起是为了完成某一个独立的功能,则该模块的内聚是功能内聚。功能内聚的内聚度最高,评分10分。

例如,在每个类中均会封装一些Get和Set方法,这些方法完成了类属性的读/写操作。它们均能满足功能内聚。

2.顺序内聚

模块内部各部分彼此紧密联系,为实现某一个功能结合在一起,并按照顺序方式执行,则该模块的内聚是顺序内聚。顺序内聚仍属于高聚度,仅次于功能内聚,评分9分。

例如,某模块逐条地读入学生的软件工程课程的百分制成绩,然后根据成绩的评定标准评定出“优”“良”“中”“及格”和“不及格”。该模块必包含了“读学生成绩”和“评定学生等级”两个部分,这两个部分彼此紧密联系,即前者的输出直接作为输入提交给后者,故它们的执行是顺序的,而该模块满足顺序内聚。

3.通信内聚

模块内部的所有元素都使用相同的输入数据或产生相同的输出结果,则该模块的内聚是通信内聚。通信内聚属于中等程度的内聚,仅次于顺序内聚,评分7分。

例如,某模块A包括两个部分“产生工资报表”和“计算平均工资”,这两个子模块均需读入职工的工资信息,且它们之间没有顺序关系,彼此较独立,则模块A满足通信内聚。如下图所示:

img46

图4.11 通信内聚的例子

4.过程内聚

模块内部的所有元素彼此相关,但必须遵循特定的过程次序执行,则该模块是过程内聚。过程内聚的另一种描述:将程序流程图中的某一过程部分划分出来,则每一过程部分就满足过程内聚。过程内聚属于中等程度的内聚,仅次于顺序内聚,评分5分。

例如,下图的“统计并打印成绩单”模块有两个部分,这两个部分被划分出来之后变成了“统计成绩”和“打印成绩”两个子模块,这两个子模块组合在一起实现“统计并打印成绩单”,而分解之后,它们虽然都完成单一功能,但只属于其他模块的一个过程。则这些模块属于过程内聚模块。

img47

图4.12 过程内聚的例子

5.时间内聚

模块内部的所有组成部分必须在同一段时间内执行完成(如所有的初始化或终止工作),则该模块是时间内聚。时间内聚是一种低内聚,模块各组成部分之间的联系仅是时间,内聚度很低,评分3分。

例如,某初始化模块由初始化公共数据区、初始化数据表等多个子模块组成,这些子模块彼此独立,但必须在同一个时间段内执行完成,故该模块满足时间内聚。同理,在面向对象程序设计的“构造函数”和“析构函数”有时就是满足时间内聚的。

6.逻辑内聚

模块内部的各组成部分除了通过逻辑变量(也称控制参数)联系之外无任何联系,则该模块是逻辑内聚。逻辑内聚也是一种低内聚。发生逻辑内聚的模块必是从其父模块接收了逻辑变量。因此,一个模块内部发生了逻辑内聚也就意味着模块之间发生了控制耦合,内聚和耦合是相关的,评分1分。

在下图中调用模块向被调用模块传递了一个逻辑变量,该变量在被调用模块中选择“读一个记录”和“写一个记录”的其中之一执行,而“读一个记录”和“写一个记录”两模块之间无任何联系,故被调用模块是一个逻辑内聚的模块。而调用模块和被调用模块之间的耦合则是控制耦合。需要采用一定的方法对其进行改造,以降低模块间的耦合,提高模块的内聚。

img48

图4.13 逻辑内聚的例子

7.偶然内聚

模块内部的所有组成部分完成了一组任务,这些任务间即使有联系,也非常松散,则该模块是偶然内聚。偶然内聚的内聚度最低,组成模块的元素之间没有实质性的联系,其修改、测试、维护都非常困难,应该坚决避免。评分0分。

对于模块内聚在设计时有如下原则:模块内聚更应重视,尽量追求功能内聚,少用逻辑内聚和偶然内聚,顺序内聚和通信内聚可以使用。此外,没有必要精确定义内聚的级别,只要能够识别出低内聚的模块即可。

三、模块独立性

模块独立性的本质就是设计高内聚、低耦合的软件结构。因此,内聚和耦合是衡量模块独立性的定性标准。此外,从上述的分析也可发现耦合和内聚是相互的,在提高模块内聚的同时也可能会降低模块间的耦合。具体提高模块独立性的主要方法是分解和合并。

例如,图4.8的例子是一个特征耦合,现需要降低模块间的耦合。仔细分析模块间的接口发现:“计算水电费”模块仅需传递一个简单参数“本月用水量”给“计算水费”模块即可完成指定功能,故模块接口的改造如图4.14所示。经过改造后模块间的耦合变成了数据耦合。

例如,图4.9的例子中A和B之间属于控制耦合,而B模块则是逻辑内聚的模块,现需要降低模块间的耦合,同时提高B的内聚。仔细分析B模块,由于组成它的两部分彼此不相关,故可将其分解为两个独立的子模块,改造后如图4.15所示。经过改造后模块间的耦合变成数据耦合,而分解后的两个子模块的内聚也必然提高。(请参考4.3.2内容)

img49

图4.14 改造特征耦合为数据耦合

img50

图4.15 改造控制耦合为数据耦合

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈