高内聚,低耦合

来源:互联网 发布:淘宝店怎么刷流量群 编辑:程序博客网 时间:2024/05/13 10:22

一个软件是由多个子程序组装而成,而一个程序由多个模块(方法)构成。“高内聚,低耦合”主要阐述的面向对象系统中,各个类需要职责分离的思想。

耦合度

定义

划分模块的一个准则就是高内聚低耦合。模块间的耦合度(Coupling)是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。

耦合的强度依赖于以下几个因素:

  • 一个模块对另一个模块的调用
  • 一个模块向另一个模块传递的数据量
  • 一个模块施加到另一个模块的控制的多少
  • 模块之间接口的复杂程度

耦合的强弱(从弱到强)

  • 非直接耦合:两个模块之间没有直接关系,之间的联系完全是通过主模块的控制和调用来实现的。
  • 数据耦合:一个模块访问另一个模块,彼此之间通过简单的数据参数交换输入输出信息。这里的简单数据参数不同于控制参数、公共数据结构或外部变量。
  • 标记耦合:如一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构的子结构,不是简单变量。
  • 控制耦合:一个模块通过传递开关、标志、名字等控制信息,明显的控制选择另一个模块的功能。
  • 外部耦合:一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数传递该全局变量的信息。
  • 公共耦合:一组模块都访问同一个公共数据环境,该公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等
  • 内容耦合:一个模块直接修改另一个模块的数据,或直接转入另一个模块

为什么要低耦合

高耦合的项目不利于延展和后期维护。必要的耦合不可否认,没有耦合程序就做不成事,但是降低模块间的不必要的耦合能减少模块间的影响,防止对某一模块修改所引起的“牵一发而动全身”的水波效应,保证系统顺利进行。

降低耦合度的方法

1、少使用类的继承,多用接口隐藏实现的细节。 Java面向对象编程引入接口除了支持多态外, 隐藏实现细节也是其中一个目的。

2、模块的功能化分尽可能的单一,道理也很简单,功能单一的模块供其它模块调用的机会就少。(其实这是高内聚的一种说法,高内聚低耦合一般同时出现,为了限制篇幅,我们将在以后的版期中讨论)。

3、遵循一个定义只在一个地方出现。

4、少使用全局变量。

5、类属性和方法的声明少用public,多用private关键字,

6、多用设计模式,比如采用MVC的设计模式就可以降低界面与业务逻辑的耦合度。

7、尽量不用“硬编码”的方式写程序,同时也尽量避免直接用SQL语句操作数据库。

8、最后当然就是避免直接操作或调用其它模块或类(内容耦合);如果模块间必须存在耦合,原则上尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,避免使用内容耦合。

内聚度

定义

  1. 内聚:表示内部聚集,关联的长度,高内聚就是指高度的聚集和关联。每一个类完成特定的独立的功能,这个就是高内聚。

  2. 内聚度是指元素之间联系的紧密程度,模块的内聚种类通常可分为7种,按其内聚度从低到高的次序依次为:偶然内聚、逻辑内聚、瞬时内聚、过程内聚、通信内聚、顺序内聚、功能内聚。

建议

  • 模块只对外暴露最小限度的接口,形成最低的依赖关系。
  • 只要对外接口不变,模块内部的修改,就不得影响其他模块。
  • 删除一个模块,应当只影响有依赖关系的其他模块,而不应该影响其他无关部分。

高内聚低耦合

人类同一时间只能专注于一小部分的内容。“高内聚。低耦合”就是为了满足人类的这个特点——小尺度上只专注一个模块,局部的编码工作才能进行。大尺度上把具体的代码转化为一些抽象的“模块”和“依赖关系”,才能够抓大放小,把握住程序的脉络,拼合出一个完整的产品。

类之间的设置应该要低耦合,但是每个类应该要高内聚.

耦合是类之间相互依赖的尺度.如果每个对象都有引用其它所有的对象,那么就有高耦合,这是不合乎要求的,因为在两个对象之间,潜在性地流动了太多信息.低耦合是合乎要求的:它意味着对象彼此之间更独立的工作.低耦合最小化了修改一个类而导致也要修改其它类的”连锁反应”.

内聚是一个类中变量与方法连接强度的尺度.高内聚是值得要的,因为它意味着类可以更好地执行一项工作.低内聚是不好的,因为它表明类中的元素之间很少相关.成分之间相互有关联的模块是合乎要求的.每个方法也应该高内聚.大多数的方法只执行一个功能.不要在方法中添加’额外’的指令,这样会导致方法执行更多的函数.

推广开来说,这个思想并不限于类与类之间的关系。模块和模块,子系统之间也都要遵守这个原则,才可以设计出延展性比较强的系统。

### 例子

两块电路板之间的接线就是耦合,接线越多,电路越复杂,以至于连电路设计者自己都被绕蒙了。一旦发现错误,头绪太多很难理清,即所谓维护性变差。想往电路里接入更多板子难度也会加大,即所谓扩展性变差。就算勉强把电路跑通了,同样的接线方法也很难在其他电路中复制,即所谓复用性差。这就是高耦合的坏处。

尽管耦合有种种坏处,但是又不可避免,因为没有耦合电路就跑不起来。怎么办呢?有个解决方法就是把耦合性尽可能藏起来。一块芯片内部电路极其复杂,但是对于外界来说它的内部电路无关紧要。这种把耦合性尽可能藏起来的做法就叫解耦,对内部而言就是高内聚,对外界而言就是低耦合。逻辑效果上就是进行了一层抽象。使得外部可以把芯片视作一个整体,只需要关心它有哪些接口,而这些接口,实际上也是耦合,只不过已经是最小化的耦合了。

有了这样一层抽象之后,工程师就可以不去关心具体的电路实现,玩纯粹的逻辑。这就催生了编程语言。所以编程语言本身已经是在底层硬件解耦的基础上所做的高度抽象了。而软件工程中提到的狭义上的解耦,是指在编程语言(确切的说是用编程语言编制的程序)基础上进行更高层次的解耦,从而获得更高层次的抽象。这样一层层解耦抽象上去,包括操作系统和应用软件在内的整个软件大厦就建造出来了。但是追根溯源,耦合与解耦概念的起源还是在硬件层次上,而软件本身其实就是经过解耦的硬件基础上的抽象。