文章目录
一、耦合
1、独立
即两个模块独立工作,没有交互关系,是理想的模块状态。
c++简单实例:
int puls(int a, int b){
return a + b;
}
string splicing(string a, string b){
return a+b;
}
2、数据耦合
两个模块之间,只通过参数交换数据
C++简单实例:
class initial{
public:
int a = 1;
int b = 2;
};
class computation{
public:
int multi(initial A) {
int x = A.a;
int y = A.b;
return ceshi = x * y;
}
private:
int ceshi;
};
int main(){
computation a;
initial A;
cout << a.multi(A) << endl;
}
initial负责初始化,computation负责计算,两者只通过参数进行数据交换,即为数据耦合
3、控制耦合
两个模块之间交换信息有控制信息,包括数据类型的控制信息
(控制耦合增加了系统的复杂性,并且往往是多余的,通常可以通过模块分解,用数据耦合代替)
C++简单实例:
class client{
public:
client(bool vip){this->VIP = vip;}
bool getClient(){return VIP;}
private:
bool VIP;
};
class company{
public:
void Service(client A){
if(A.getClient())
cout << "一流服务" << endl;
else
cout << "普通服务" << endl;
}
};
int main(){
client A(1);
company B;
B.Service(A);
return 0;
}
客户类A将客户类型作为数据传入公司类,并且能够控制公司类的表现,两者是控制耦合
4、特征耦合
整个数据结构作为参数传递时,被调用的模块只需要使用其中一部分元素。
(通俗来讲,传递的参数包含多种数据,模块只用了其中一部分,并没有全部使用)
C++简单实例:
class Client{
public:
Client(string Name){
name = Name;
}
void payAcc(float *money){
cout << "已付款住宿费" << money[0] << "元" << endl;
}
void payEntr(float *money){
cout << "已付款门票费" << money[1] << "元" << endl;
}
private:
string name;
};
class traBill{
public:
traBill (float accFee, float entrFee){
bill[0] = accFee;
bill[1] = entrFee;
}
float *getBill(){
return bill;
}
private:
float bill[2]; //bill[0]: 住宿费 bill[1]:景点门票
};
int main(){
traBill B(109.00 , 666.66);
Client A("XiaoMing");
A.payAcc(B.getBill());
A.payEntr(B.getBill());
return 0;
}
在上述例子中旅游费用B类传递给用户A的数据结构(账单数组)中,A类每次分别只取用部分数据,即构成特征耦合。
显而易见,这种耦合,是能够较为轻易的简化为数据耦合的(将B类中账单数组拆分,或者将A类中付款功能合并)
5、公共环境耦合
当两个或者多个模块共同使用一个公共数据环境时,它们之间的耦合即为公共环境耦合,其复杂度随着模块数量的增加显著增加。
公共环境可以是:全程变量、共享的通信区、内存的公共覆盖区、任何存储介质上的文件、物理设备等
6、内容耦合(耦合程度最高)
出现以下情况即发生内容耦合:
1、一个模块访问另一个模块的内部数据;
2、一个模块不通过正常入口而转移到另外一个模块的内部;
3、两个模块有一部分程序代码重叠(只出现在汇编中);
4、一个模块有多个入口(即有多个功能)
内容耦合极易出现程序错误,大多高级语言在设计时已经静止出现内容耦合。
二、内聚
内聚程度从低到高:
低程度内聚:偶然内聚<逻辑内聚<时间内聚
中程度内聚:过程内聚<通信内聚、
高程度内聚:顺序内聚<功能内聚
1、偶然内聚
一个模块完成一组任务,任务与任务之间关系松散,或者没有关系
例如类A中有字符串拼接和浮点型乘积,两个功能之间没有关系;
class A{
public:
string spe(string a, string b){
return a + b;
}
float mul(fliat a, float b){
return a * b;
}
};
2、逻辑内聚
一个模块完成的任务在逻辑上属于相同或相似的一类。
例如:计算类中有计算差和计算和的功能,两者逻辑上都属于计算
class compute{
public:
compute(int X, int Y,int A, int B){
this->x = X;
this->y = Y;
this->a = A;
this->b = B;
}
int sum(){
return a+b;
}
int sub(){
return x-y;
}
private:
int x;
int y;
int a;
int b;
}
3、时间内聚
一个模块包含的任务必须在同一段时间内执行;
例如,看博客和收藏、点赞、关注(不是【狗头】)
操作系统中的开机模块,类的初始化等
4、过程内聚
一个模块内的处理元素是相关的,并以特定次序执行。
class average{
public:
average(int x, int y){
this->a = x;
this->b = y;
}
void sum(){
this->c = a + b;
}
int getAverage(){
return c/2;
}
private:
int a;
int b;
int c;
}
上述实例中计算平均值类中,计算和的方法和计算平均值的方法必须依次执行,整个模块具有过程内聚
5、通信内聚
模块中所有元素都使用同一个输入数据或者产生同一个输出数据。
class compute{
public:
compute(int A, int B){
this->a = A;
this->b = B;
}
int sum(){
return a+b;
}
int sub(){
return a-b;
}
private:
int a;
int b;
};
在上述案例中,sum和sub方法都使用变量a和变量b,但是两者没有执行顺序的要求,构成通信内聚。
6、顺序内聚
模块内的处理元素和同一个功能密切相关,并且处理顺序必须顺序执行。
class sqaDif{
public:
sqaDif(int A, int B){
this->a = A;
this->b = B;
}
void comSqa(){
a *= a;
b *= b;
}
int getsqaDif(){
return a-b
}
private:
int a;
int b;
}
上述功能实现平方差的功能,必须先计算a和b的平方,再求差,都对a和b进行操作,具有顺序内聚
7、功能内聚
模块内所有处理元素属于一个整体(缺一不可),完成一个单一的功能。
int fac(int n){
int f;
if(n == 1 || n == 0 )
f = 1;
else
f = n*fac(n-1)
return f
}
上述实例只完成计算n!,功能单一
都看到这里了,准研究生们给个赞不过分吧๐·°(৹˃̵﹏˂̵৹)°·๐