Published on

内聚性和耦合性

Authors

内聚性

内聚性(Cohesion),是一软件度量,是指机能相关的程序组合成一模块的程度,或是各机能凝聚的状态或程度。是结构化分析的重要概念之一。量测内聚性的方式很多,有些方法是由分析源代码,得到非量化的结果,有些方法则是检查源代码的文本特征,以得到内聚性的量化分数。内聚性是属于顺序式的量测量,一般会以“高内聚性”或“低内聚性”来表示。一般会希望程序的模块有高内聚性,因为高内聚性一般和许多理想的软件特性有关,包括鲁棒性、可靠度、可复用性及易懂性(understandability)等特性,而低内聚性一般也代表不易维护、不易测试、不易复用以及难以理解。

而耦合性(Coupling)是一个和内聚性相对的概念。一般而言高内聚性代表低耦合性,反之亦然。内聚性是由赖瑞·康斯坦丁所提出,是以实务上可减少维护及修改的“好”软件的特性为基础。

高内聚性

在计算机科学中,内聚性是指机能相关的程序组合成一模块的程度。应用在面向对象编程中,若服务特定类型的方法在许多方面都很类似,则此类型即有高内聚性。在一个高内聚性的系统中,代码可读性及复用的可能性都会提高,程序虽然复杂,但可被管理。

以下的情形会降低程序的内聚性:

  • 许多机能封装在一类型内,可以借由方法供外界使用,但机能彼此类似之处不多。
  • 在方法中进行许多不同的机能,使用的是相关性低或不相关的资料。

低内聚性的缺点

  • 增加理解模块的困难度。
  • 增加维护系统的困难度,因为一个逻辑修改会影响许多模块,而一个模块的修改会使得一些相关模块也要修改。
  • 增加模块复用困难度,因为大部分的应用程序无法复用一个由许多不一定相关的机能组成的模块。

内聚性的类型

内聚性是一种非量化的量测,可利用评量规准来确认待确认源代码的内聚性的分类。内聚性的分类如下,由低到高排列:

偶然内聚性(Coincidental cohesion,最低)

偶然内聚性是指模块中的机能只是刚好放在一起,模块中各机能之间唯一的关系是其位在同一个模块中(例如:“工具”模块)。

逻辑内聚性(Logical cohesion)

逻辑内聚性是只要机能只要在逻辑上分为同一类,不论各机能的本质是否有很大差异,就将这些机能放在同一模块中(例如将所有的鼠标和键盘都放在输入处理副程序中)。模块内执行几个逻辑上相似的功能,通过参数确定该模块完成哪一个功能。

时间性内聚性(Temporal cohesion)

时间性内聚性是指将相近时间点执行的程序,放在同一个模块中(例如在捕捉到一个异常后调用一函数,在函数中关闭已开启的文件、产生错误日志、并告知用户)。

程序内聚性(Procedural cohesion)

程序内聚性是指依一组会依照固定顺序执行的程序放在同一个模块中(例如一个函数检查文件的权限,之后开启文件)。

联系内聚性/信息内聚/通信内聚(Communicational cohesion)

联系内聚性是指模块中的机能因为处理相同的资料或者指各处理使用相同的输入数据或者产生相同的输出数据,因此放在同一个模块中(例如一个模块中的许多机能都访问同一个记录)。

依序内聚性/顺序内聚(Sequential cohesion)

依序内聚性是指模块中的各机能彼此的输入及输出资料相关,一模块的输出资料是另一个模块的输入,类似工厂的生产线(例如一个模块先读取文件中的资料,之后再处理资料)。

功能内聚性(Functional cohesion,最高)

功能内聚性是指模块中的各机能是因为它们都对模块中单一明确定义的任务有贡献(例如XML字符串的词法分析)。

耦合性

耦合性(Coupling)或称耦合力或耦合度,是一种软件度量,是指一程序中,模块及模块之间信息或参数依赖的程度。低耦合性是结构良好程序的特性,低耦合性程序的可读性及可维护性会比较好。

耦合性的分类

耦合性可以是低耦合性(或称为松散耦合),也可以是高耦合性(或称为紧密耦合)。以下列出一些耦合性的分类,从高到低依序排列:

内容耦合(content coupling,耦合度最高)

也称为病态耦合(pathological coupling)当一个模块直接使用另一个模块的内部数据,或通过非正常入口而转入另一个模块内部。

共享耦合/公共耦合(common coupling)

也称为全局耦合(global coupling.)指通过一个公共数据环境相互作用的那些模块间的耦合。公共耦合的复杂程度随耦合模块的个数增加而增加。

外部耦合(external coupling)

发生在二个模块共享一个外加的资料格式、通信协议或是设备界面,基本上和模块和外部工具及设备的沟通有关。

控制耦合(control coupling)

指一个模块调用另一个模块时,传递的是控制变量(如开关、标志等),被调模块通过该控制变量的值有选择地执行块内某一功能;

特征耦合/标记耦合(stamp coupling)

也称为数据结构耦合,是指几个模块共享一个复杂的数据结构,如高级语言中的数组名、记录名、文件名等这些名字即标记,其实传递的是这个数据结构的地址;

资料耦合/数据耦合(data coupling)

是指模块借由传入值共享资料,每一个资料都是最基本的资料,而且只分享这些资料(例如传递一个整数给计算平方根的函数)。

消息耦合(message coupling,是无耦合之外,耦合度最低的耦合)

可以借由以下二个方式达成:状态的去中心化(例如在对象中),组件间利用传入值或消息传递来通信。

无耦合

模块完全不和其他模块交换信息。

面向对象编程

子类耦合(subclass coupling) 描述子类和父类之间的关系,子类链接到父类,但父类没有链接到子类。

时空耦合(temporal coupling) 二个动作只因为同时间发生,就被包装在一个模块中。

高耦合的缺点

高耦合的系统在开发阶段有以下的缺点:

  1. 一个模块的修改会产生涟漪效应,其他模块也需随之修改。
  2. 由于模块之间的相依性,模块的组合会需要更多的精力及时间。
  3. 由于一个模块有许多的相依模块,模块的可复用性低。