• 内聚和耦合的介绍


    软件设计“内聚度”“耦合度”介绍
     
     
    一、联系
     
        当个程序段或语句(指令)引用了其它程序段或语句(指令)中所定义或使用的数据名(即存贮区、地址等)或代码时,他们之间就发生了联系。一个程序被划分为若干模块时,联系既可存在于模块之间,也可存在于一个模块内的程序段或语句之间,即模块内部。联系反映了系统中程序段或语句之间的关系,不同类型的联系构成不同质量的系统。因此,联系是系统设计必须考虑的重要问题。
     
        系统被分成若干模块后,模块同模块的联系称为块间联系;一个模块内部各成份的联系称为块内联系。显然,模块之间的联系多,则模块的相对独立性就差,系统结构就混乱;相反,模块间的联系少,各个模块相对独立性就强,系统结构就比较理想。同时,一个模块内部各成份联系越紧密,该模块越易理解和维护。
     
     
    二、评判模块结构的标准
     
        1.模块独立性
       
        模块化是软件设计和开发的基本原则和方法,是概要设计最主要的工作。模块的划分应遵循一定的要求,以保证模块划分合理,并进一步保证以此为依据开发出的软件系统可靠性强,易于理解和维护。根据软件设计的模块化、抽象、信息隐蔽和局部化等原则,可直接得出模块化独立性的概念。所谓模块独立性,即:不同模块相互之间联系尽可能少,应尽可能减少公共的变量和数据结构;一个模块应尽可能在逻辑上独立,有完整单一的功能。
     
        模块独立性(Moduleindependence)是软件设计的重要原则。具有良好独立性的模块划分,模块功能完整独立,数据接口简单,程序易于实现,易于理解和维护。独立性限制了错误的作用范围,使错误易于排除,因而可使软件开发速度快,质量高。
     
        为了进一步测量和分析模块独立性,软件工程学引入了两个概念,从两个方面来定性地度量模块独立性的程度,这两个概念是模块的内聚度和模块的耦合度
     
        2.块内联系的度量——内聚度
     
        软件概要设计是以需求分析所产生的文档为依据,着手解决实现“需求”的软件体系结构,简称软件结构。这一阶段确定软件结构的具体任务是将系统分解成模块,确定各模块的功能及调用关系,将用户的需求分配到适当的位置上去,得出系统的结构图。
     
        软件概要设计的原则是模块化、抽象化和信息隐藏,要达到这些原则,就要求模块具有独立性。模块内聚度用于衡量模块内部各成分之间彼此结合的紧密程度,模块内聚度由强到弱的顺序如图:
     
        高<----------------------------- 内聚度 -----------------------------低
        | 功能内聚 | 信息内聚 | 通信内聚 | 过程内聚 | 时间内聚 | 逻辑内聚 | 巧合内聚 |
        强<--------------------------- 模块独立性 ----------------------------弱
     
        1> 功能内聚 (Functional Cohesion)
     
        功能内聚是内聚度最高的一种模块类型。如果模块仅完成一个单一的功能,且该模块的所有部分是实现这一功能所必须的,没有多余的语句,则该模块为功能内聚。功能内聚模块的结构紧凑、界面清晰,易于理解和维护,因而可靠性强;又由于其功能单一,故复用率高。所以它是模块划分时应注意追求的一种模块类型。
     
        2> 信息内聚 (Informational Cohesion)
     
        这种模块完成多个功能,各个功能都在同一数据结构上操作,每一项功能都一个唯一的入口。这个模块将根据不同的要求,确定该执行哪一个功能。由于这个模块的所有功能都是基于同一数据结构(符号表),因此它是一个信息内聚模块。
     
        信息内聚模块可以看作多个功能内聚模块的组合,并且达到信息的隐蔽。即把某个数据结构、资源或设备隐蔽在一个模块内,不为别的模块所知晓。如果一个模块的各个成分和同一个功能密切相关,而且一个成分的输出作为另一个成分的输入,则称为顺序内聚
     
        顺序内聚的模块内,后执行的语句或语句段往往依赖先执行的语句或语句段,以先执行的部分为条件。由于模块内各处理元素间存在着这种逻辑联系,所以顺序内聚模块的可理解性很强,属高内聚度类型模块。
     
        3> 通信内聚 (Communication Cohesion)
     
        若一个模块中的各处理元素需引用共同的数据(同一数据项、数据区或文件),即使用了相同的输入数据或输出数据,则称其元素间的联系为通信内聚。通信内聚的各部分间是借助共同使用的数据联系在一起的,故有较好的可理解性。通常内聚模块是通过数据流图来定义的。
     
        4> 过程内聚 (Procedural Cohesion)
     
        如果一个模块内的各个处理元素是相关的,而且必须按固定的次序执行,这种内聚就叫做过程内聚。过程内聚的各模块内往往体现为有次序的流程。
     
        在使用流程图作为工具设计程序时,把流程图中的某一部分划出组成模块,就得到过程内聚模块。例如把流程图中的循环部分、判定部分、计算部分分成三个模块,则这三个模块都是过程内聚的。
     
        5> 时间内聚 (Classical Cohesion)
     
        时间内聚又称为经典内聚或瞬时内聚。时间内聚是指一个模块中包含的任务需要在同一时间内执行(如初始化,结束等所需操作)。与巧合内聚和逻辑内聚相比,这种内聚类型要稍强些,因为至少在时间上,这些任务可以一起完成。但时间内聚和偶然内聚、逻辑内聚一样,都属低内聚度类型。
     
        6> 逻辑内聚 (Logical Cohesion)
     
        一个模块完成的任务在逻辑上属于相同或相似的一类(例如用一个模块产生各种类型的输出),则该种模块内的联系称为逻辑内聚。每次调用模块时,由传送给模块的判定参数来确定该模块应执行哪一种功能。
     
        逻辑内聚的模块各成分之间在功能上并无关系,即使局部功能的修改有时也会影响全局,因此主要的困难有:
     
        ① 修改困难,调用模块中有一个要对其改动,还要考虑到其它调用模块;
        ② 模块内需要增加开关,以判别是谁调用,因而增加了块间联系;
        ③ 实际上每次调用只执行模块中的一部分,而其它部分也一同被装入内存,因而效率不高。
     
        7> 巧合内聚(Coincidental Cohesion)
     
        块内的各个任务(通过语句或指令来实现的)没有什么有意义的联系,它们之所以能构成一个模块完全是偶然的原因。
     
        这类模块内部没有实质性的联系,很可能在某种情况下一个调用模块需要对它修改而别的模块不需要。这时就很难处理。同时,这种模块的含义也不易理解,甚至难以为它取一个合适的名字,偶然内聚的模块也难于测试。所以,在空间允许的情况下,不应使用这种模块。
     
        2.块间联系的度量——耦合度
     
        耦合度是对一个软件结构内不同模块之间互连程度的度量。耦合强弱取决于模块间接口的复杂程度、进入访问一个模块的点及通过接口的数据。在软件设计中应该追求尽可能松散的耦合系统,在这样的系统中可以研究、测试或修改、维护任何一个模块,而不需要对系统的其它模块有很多的了解或影响其它模块的实现。此外,当某处发生错误时,低耦合度系统的错误传播的范围相对小些。
     
        耦合度取决于各个模块间接口的复杂程度、调用模块的方式,以及哪些信息通过接口。耦合度的强弱依赖以下几个因素:
     
        (1)一个模块对另一个模块的调用
        (2)一个模块向另一个模块传递的数据量
        (3)一个模块施加到另一个模块的控制的多少
        (4)模块之间接口的复杂度
     
        一般模块之间可能的连接方式有以下几种,耦合度由低到高如下所示:
     
        低<------------------------------ 耦合性 ------------------------------低
        | 非直接耦合 | 数据耦合 | 标记耦合 | 控制耦合 | 外部耦合 | 公共耦合 | 内容耦合 |
        强<---------------------------- 模块独立性 -----------------------------弱
     
        1> 非直接耦合 (Nondirective Coupling)
     
        指两个模块彼此完全独立,没有直接联系。它们之间的唯一联系仅仅在于它们同属于一个软件系统或同有一个上层模块。这是耦合程度最低的一种。当然,系统中只可能有一部分模块属此种联系,因为一个程序系统中不可能所有的模块都完全没有联系。
     
        2> 数据耦合 (Data Coupling)
     
        两个模块彼此交换数据,如一个模块的输出数据是另一个模块的输入数据,或一个模块带参数调用另一个模块,下层模块又返回参数,则称为数据耦合。注意这里的数据指的是简单数据,而不包括控制参数、公共数据结构或外部变量。
     
        应该说,在一个软件系统中,此种耦合是不可避免的,且有其积极意义。因为任何功能的实现都离不开数据的产生、表示和传递。数据耦合的联系程度也较低。
     
        3> 标记耦合 (Stamp Coupling)
     
        如果一组模块通过参数传递记录信息,这称为标记耦合。这个记录是某一数据结构的子结构,而不是简单变量。
     
        4> 控制耦合 (Control Coupling)
     
        如果一个模块通过开关、标志、名字等控制信息,明显得控制选择另一模块功能,这种耦合称为控制耦合。控制耦合属于中等程度的耦合,较之数据耦合模块间的联系更为紧密。但控制耦合不是一种必须存在的耦合。
     
        当被调用模块接收到控制信息作为输入参数时,说明该模块内部存在多个并列的逻辑路径,即有多个功能。控制变量用以从多个功能中选择所要执行的部分,因而控制耦合是完全可以避免的。排除控制耦合可按如下步骤进行:
     
        ① 找出模块调用时所用的一个或多个控制变量;
        ② 在被调模块中根据控制变量找出所有的流程;
        ③ 将每一个流程分解为一个独立的模块;
        ④ 将原被调模块中的流程选择部分移到上层模块,变为调用判断。
     
        通过以上变换,可以将控制耦合变为数据耦合。由于控制耦合增加了设计和理解的复杂程度,因此在模块设计时要尽量避免使用。当然,如果模块内每一个控制流程规模相对较小,彼此共性较多,使用控制耦合还是合算的。
     
        5> 外部耦合 (External Coupling)
     
        一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数传递该全局变量的信息,则称之为外部耦合。
     
        6> 公共耦合 (Common Coupling)
     
        公共耦合又称公共环境耦合或数据区耦合。若多个模块对同一个数据区进行存取操作,它们之间的关系称为公共耦合。公共数据区可以是全程变量、共享的数据区、内存的公共复盖区、外存上的文件、物理设备等。当两个模块共享的数据很多,通过参数传递可能不方便时,可以使用公共耦合。公共耦合共享数据区的模块越多,数据区的规模越大,则耦合程度越强。公共耦合最弱的一种形式是:两个模块共享一个数据变量,一个模块只向里写数据,另一个模块只从里读数据。
     
        当公共耦合程度很强时,会造成关系错综复杂,难以控制,错误传递机会增加,系统可靠性降低,可理解、维护性差。
     
        7> 内容耦合 (Content Coupling)
     
        内容耦合是耦合程序最高的一种形式。若一个模块直接访问另一模块的内部代码或数据,即出现内容耦合。内容耦合的存在严重破坏了模块的独立性和系统的结构化,代码互相纠缠,运行错综复杂,程序的静态结构和动态结构很不一致,其恶劣结果往往不可预测。 内容耦合往往表现为以下几种形式:
     
        ①一个模块访问另一模块的内部代码或数据;
        ②一个模块不通过正常入口而转到另一个模块的内部(如使用GOTO语句或JMP指令直接进入另一模块内部);
        ③两个模块有一部分代码重迭(可能出现在汇编程序中,在一些非结构化的高级语言,如COBOL中也可能出现);
        ④一个模块有多个入口(这意味着一个模块有多种功能)。
     
        一般讲,在模块划分时,应当尽量使用数据耦合。少用控制耦合(尽量转成数据耦合),限制公共耦合的范围,完全不用内容耦合。
  • 相关阅读:
    I第五章:(1)Hystrix 断路器
    第四章—Netty:(1)Netty概述
    I第四章:(1)Feign 负载均衡
    第三章—Java NIO编程:(9)AIO及三种IO对比
    I第六章:(1)Zuul路由网关
    第五章—Netty高性能架构设计:(2)Reactor线程模式
    Pytest动态为用例添加mark标记
    Postman使用简介
    Fiddler抓包使用简介
    使用正则解析Python赋值及函数调用表达式
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8203637.html
Copyright © 2020-2023  润新知