参考:
1.维基百科 耦合性
2.Component Coupling
解耦的目的就是达到, A模块调用B时, 不需要知道B的内部实现
耦合等级: 高耦合->低耦合
红色为常见的耦合,->后面基本就是这篇文章的3条总结.如果能明白就不需要继续看了
内容耦合
共用耦合common coupling->尽量不要全局变量, --->>各个模块不依赖全局变量
外部耦合
控制耦合control coupling ->不要用A模块的flag去控制B模块. --->>A不需要知道B的结构
特征耦合stamp coupling or data struct coupling->(如果模块只用到了结构体中的几个数据)不用结构体做参数, 用结构体内部原始类型做参数. --->>各个模块不再依赖结构体
数据耦合
消息耦合
无耦合
内容耦合(content coupling,耦合度最高)
也称为病态耦合(pathological coupling)是指一个模块依赖另一个模块的内部作业(例如,访问另一个模块的局域变量),因此修改第二个模块处理的数据(位置、形态、时序)也就影响了第一个模块。
//A模块使用goto语句跳入B模块, 则A依赖B的内部状态,产生了内容依赖
//不知道其他情况
//不要使用goto
int Func1 (int a)
{
printf ("In Func1\n");
a += 2;
<span style="color:#ff0000;">goto F2A;</span>
return a;
}
void Func2 (void)
{
printf("In Func2\n");
F2A:
printf("At Func2A\n");
}
共用耦合(common coupling)
//尽量不用全局变量, 如果用的话, 尽量只有一处修改全局变量
也称为全局耦合(global coupling.)是指二个模块分享同一个全局变量,因此修改这个共享的资源也就要更动所有用到此资源的模块。
int Function1 (int a)
{
if (a > 0)
{
<span style="color:#ff0000;">myGlobalVar</span>++;
a = 0;
}
return a;
}
void Function2 (void)
{
if(<span style="color:#ff0000;">myGlobalVar</span> > 0)
{
<span style="color:#ff0000;">myGlobalVar</span> = 42;
}
else
{
<span style="color:#ff0000;">myGlobalVar</span> = -1;
}
}
外部耦合(external coupling)//
没遇见过,不太太理解
发生在二个模块共用一个外加的数据格式、通信协议或是设备界面,基本上和模块和外部工具及设备的沟通有关。
控制耦合(control coupling)
是指一个模块借由传递“要做什么”的信息,控制另一个模块的流程(例如传递相关的旗标)
//A中flag传给B, B根据flag不同而做出不同的操作,A中调用B.operate(flag);
//解决方法: 参考策略模式
//1.将flag的产生,转移到B中. 这样A就不需要知道B的内部.
//2.如果AB是函数, 将B改为operate1, operate2, operate3.一个函数只有一个功能
void PrintBoard (char board[ROWS][COLS], int rows, int cols, int <span style="color:#ff0000;">done</span>)
{
int i, j;
printf(" 0 1 2 3 4 5 6 7 8 9\n");
printf(" -----------------------------------------\n");
for(i = 0; i < rows; i++)
{
printf("%d ", i);
for(j = 0; j < cols; j++)
{
<span style="color:#ff0000;">if(done)</span>
{
printf("| %c ", board[i][j]);
}
<span style="color:#ff0000;">else</span>
{
if(board[i][j] == ' ' || board[i][j] == 'O'
|| board[i][j] == 'X')
{
printf("| %c ", board[i][j]);
}
else
{
printf("| ");
}
}
}
printf("|\n");
printf(" -----------------------------------------\n");
}
}
特征耦合
<span style="color:#ff0000;">typedef struct rectangle
{
int length;
int width;
int area;
int perimeter;
int color;
double diagonal;
char symbol;
} RECTANGLE;</span>
RECTANGLE CalcArea (RECTANGLE r);
RECTANGLE CalcPerimeter (RECTANGLE r);
RECTANGLE CalcDiagonal (RECTANGLE r);
int main()
{
RECTANGLE rect1;
rect1.length = 7;
rect1.width = 6;
rect1.color = RED;
rect1.symbol = '#';
rect1 = CalcArea (rect1);
rect1 = CalcPerimeter (rect1);
rect1 = CalcDiagonal (rect1);
printf("For width: %d and length %d\n",
rect1.width, rect1.length);
printf("The area, perimeter and diagonal are\n");
printf("%d %d %f\n", rect1.area, rect1.perimeter,
rect1.diagonal);
return 0;
}
<span style="color:#ff0000;">RECTANGLE CalcArea (</span><span style="color:#33ccff;">RECTANGLE r</span><span style="color:#ff0000;">)
{
r.area = r.width * r.length;
return r;
}</span>
<span style="color:#ff0000;">RECTANGLE CalcPerimeter (</span><span style="color:#33ccff;">RECTANGLE r</span><span style="color:#ff0000;">)
{
r.perimeter = 2 * r.width + 2 * r.length;
return r;
}
RECTANGLE CalcDiagonal (<span style="background-color: rgb(51, 204, 255);">RECTANGLE r</span>)
{
r.diagonal = sqrt (r.width * r.width
+ r.length * r.length);
return r;
}</span>
数据耦合(data coupling)
//就是数据的传递(模块A中的a=10,传入到B模块中,B.fun(a)),不需要处理这种耦合
是指模块借由传入值共享数据,每一个数据都是最基本的数据,而且只分享这些数据(例如传递一个整数给计算平方根的函数)。
//对比上面的例子
<span style="color:#ff0000;">int CalcArea (</span><span style="color:#00cccc;">int width, int length</span><span style="color:#ff0000;">)
{
int area;
area = width * length;
return area;
}
int CalcPerimeter (</span><span style="color:#33ccff;">int width, int length</span><span style="color:#ff0000;">)
{
int perimeter;
perimeter = 2 * width + 2 * length;
return perimeter;
}
double CalcDiagonal (</span><span style="color:#33ccff;">int width, int length</span><span style="color:#ff0000;">)
{
double diagonal;
diagonal = sqrt (width * width
+ length * length);
return diagonal;
}</span>
消息耦合(message coupling,是无耦合之外,耦合度最低的耦合)
//不太懂,感觉和数据耦合差不多
可以借由以下二个方式达成:状态的去中心化(例如在对象中),组件间利用传入值或消息传递来通信。
无耦合:模块完全不和其他模块交换信息。