再上一篇:9 .3 模块的独立程度
上一篇:9 .3 .1 模块内聚
主页
下一篇:9 .4 模块化程序设计步骤
再下一篇:9 .5 模块化程序设计实例
文章列表

9 .3 .2 模块耦合

《程序设计基础》(基于C语言讲解) 石光华 编著 —北京: 清华大学出版社

程序设计人员设计程序算法时,不仅要考虑模块的内聚度,也要考虑模块之间信息流的传递情况。程序设计人员的目的在于保证模块的独立性,也就是说,某个模块和其他模块之间要有更少、更简单的连接方式。这些连接称为接口或耦合。

耦合是对程序结构中不同模块之间信息交换程度的度量。耦合的强弱取决于模块间接口的复杂程度,进入或访问一个模块的点,以及通过接口的数据。紧耦合意味着两个模块结构之间有更大的依赖性。由于模块间有更多个连接路径,因而发生在一个模块中的错误就有可能传播到程序的其他各部分模块。

松耦合和紧耦合是相对的。松耦合的模块更独立,并且更容易维护。

与Yourdon和Constantine 提出的内聚类型划分类似,Glenford Myers 也给出了几种类型的模块耦合。

图9-4是按照模块设计质量从最差到最好的顺序列出的5种类型的模块耦合图。需要指出的是,这些类型的耦合还没有严格的定义。它们只是Glenford Myers认为的在模块化程序设计中存在的几种耦合类型。

图9-4 模块耦合图

1 .公共耦合

公共耦合是指模块间访问同一全局数据结构(该数据结构可能是相关数据项的集合,例如一个记录或数组)的情况。当模块间采用公共耦合时,这些模块将共享某个全局数据结构。公共耦合意味着数据可以被程序中的任何模块访问和修改,这将使程序很难阅读和理解。

【例9-7】 程序中的add_score()模块和float average_score()模块访问同一全局数据结构iscore[SIZE],形成了公共耦合关系如下。

#include < stdio .h>

#define SIZE 5

136 程序设计基础

int iscore[SIZE] ={0};

voidadd_score(int n);

float average_score();

void main()

{

int iindex=0;

float fresult=0 .0;

for(iindex=0;iindex

{

printf(″Please input age :\n″);

scanf(″%d″,&iscore[iindex]);

}

add_score(20);

fresult=average_score();

printf(″average score is %f″,fresult);

}

voidadd_score(int n)

{

int iindex;

for(iindex=0; iindex

iscore[iindex] =iscore[iindex] +n;

}

float average_score()

{

int iindex;

float ftmp=0;

for(iindex=0; iindex

ftmp=iscore[iindex] +ftmp;

returnftmp/ iindex;

}

2 .外部耦合

外部耦合是指两个或更多的模块访问同一全局数据变量,而不是同一全局数据结构

的情况。

第9章 模块化程序设计 137

外部耦合与公共耦合是相似的,外部耦合访问的全局数据是基本数据项,而不是数据结构。由于全局数据有更简单的结构,因而与公共耦合相比,外部耦合被认为是更松散的耦合形式。

【例9-8】 程序中的int powerno(int ifirst,int isecond)模块和int sumno(int ifirst,int isecond)模块访问同一全局数据变量int ifirst,isecond,形成外部耦合关系如下。

#include < stdio .h>

int ifirst=0,isecond=0;

int sumno(int ifirst,int isecond);

int powerno(int ifirst,int isecond);

void main()

{

int itmp=0;

scanf(″%d%d″,&ifirst,isecond);

itmp=sumno(ifirst,isecond);

printf(″sum is %f″,itmp);

itmp=powerno(ifirst,isecond);

printf(″power is %f″,itmp);

}

int sumno(int ifirst,int isecond)

{

return ifirst+isecond;

}

int powerno(int ifirst,int isecond)

{

return ifirst * isecond;

}

3 .控制耦合

控制耦合是指两个模块间传递控制变量,并通过该变量控制另外模块逻辑关系的情况。两个模块间通过参数传递信息,这些传递信息中包含控制变量,例如程序标记或转换开关等。

控制耦合模块的弱点在于,两个模块间需要传递控制信息,这就意味着其中一个模块要了解另外一个模块的内部逻辑关系。

138 程序设计基础

【例9-9】 主模块向add_all_score模块传递控制变量icontrol的程序。

#include < stdio .h>

void main()

{

int icontrol;

scanf(″%d″,&icontrol);

add_all_score(icontrol);

}

int add_all_score(int key)

{

switch(key)

{

case 1:

add_score1();

break;

case 2:

add_score2();

break;

case 3:

add_score3();

break;

}

}

4 .标记耦合

标记耦合是指一个模块向另一个模块传递非全局的数据结构。非全局数据结构通过

参数进行传递。

标记耦合模块是一种松散耦合的情况,并保证了良好的模块化程序设计质量。两个

模块间惟一的关联是通过数据结构来传递的。任何一个模块都没有必要了解其他模块内

部的逻辑关系。

【例9-10】 模块add_scores()与模块average_score()之间通过非全局的数据结构

iscore[SIZE]形成标记耦合的程序。

#include < stdio .h>

第9章 模块化程序设计 139#define SIZE 5

voidadd_score(int n,int iscore[]);

float average_score(int iscore[]);

void main()

{

int iindex=0;

float fresult=0 .0;

int iscore[SIZE] ={0};

for(iindex=0;iindex

{

printf(″Please input age :\n″);

scanf(″%d″,&iscore[iindex]);

}

add_score(20,iscore);

fresult=average_score(iscore);

printf(″average score is %f″,fresult);

}

voidadd_score(int n,int iscore[])

{

int iindex;

for(iindex=0; iindex

iscore[iindex] =iscore[iindex] +n;

}

float average_score(int iscore[])

{

int iindex;

float ftmp=0;

for(iindex=0; iindex

ftmp=iscore[iindex] +ftmp;

returnftmp/ iindex;

}

5 .数据耦合

数据耦合是指一个模块向另一个模块传递非全局的数据变量。数据耦合和标记耦合140 程序设计基础

有些相似,只是数据耦合传递的非全局数据变量是基本数据项,而不是数据结构。

数据耦合是最松散耦合的情况,具有最好的模块化程序设计质量。两个模块间惟一

的关联是通过一个或多个基本数据项传递的。

【例9-11】 主模块向my_abs模块传递非全局的数据变量a的程序。

#include < stdio .h>

void main()

{

int x;

scanf(″%d″,&x);

printf(″%d″,my_abs(x));

}

int my_abs(int a)

{

int iresult=0;

if (a > =0)

iresult=a;

else

iresult= - a;

return iresult;

}

考虑耦合形式时应注意如下。

程序设计人员设计程序解决算法时,应该尽量遵循模块独立性及模块间信息交换量

最小的设计原则。即所设计的程序结构,应使得每个模块完成一个相对独立的特定子功

能,并且与其他模块之间的关系尽量简单。

在程序设计语言允许的情况下,应尽量使每个模块与相应的外部环境分离。为此,应

注意下面4个方面。

(1) 尽量以参数的形式向从属模块传递数据,而不要采用全局数据的形式。

(2) 把每个从属模块设计成独立的单元,只能接受外界传递给它的数据。

(3) 对某个模块所做的修改应不影响到程序的其他部分。

(4) 需要的话,可把信息传递到主调模块。

程序设计人员设计程序时,首要考虑的必须是保证所生成的模块和程序易于理解和

修改。如果所选的程序设计语言提供了惟一的全局数据,程序设计良好的标准是将紧密

耦合降低到最小限度。

第9章 模块化程序设计 141