高内聚与低耦合

内聚

即,自己管好自己的东西。当然,程序设计的不同层次,从方法、到对象/类再到整个功能、服务、架构都有内聚的概念来讲。自己的东西一定要管理好,提高自身的内聚性,最大限度的不要给其他人制造麻烦。不光如此从整个概念来审视我们自己,一个人本身是不是也应该这样子!

依赖&耦合(coupling)

a connection (like a clamp or vise) between two things so they move together

在面向对象编程中,对象自身是内聚的,保管好自身数据、完成自己的操作,对外界呈现自己的状态、行为。但是对象不可能包含全部事物、功能,所以对外开放是必要的,所以依赖别的对象或者被别的对象依赖成为必然。

很容易从字面上理解,开发中我们经常遇到对象与对象的相互依赖的情况,就像我依赖父母、人类依赖地球一样。

程序员编写模块A时,需要知道模块B的存在,需要知道模块B提供哪些功能,A对B依赖就存在

依赖耦合的最大区别在于,当我们说“A和B耦合”时,在字面含义中,A和B二者平等。

但是现实开发中,我们却总是写出“单向依赖”的代码。我们发现单向依赖不是坏事,根本不必费心消除,因为,真正的重点是,依赖关系中,被依赖方暴露的接口能不能足够“正交”和“紧凑”。

耦合即:两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象。

数据库级别、通信协议级别、操作系统级别各个模块之间都会存在着大量的耦合

其实耦合是天生的,不存在绝对不耦合。最重要的是“如何看待耦合”,耦合的本质是假设,假设越多,被打破的机率就越高,所以软件的可靠性就越低。

低耦合代表的是在软件不同级别的概念上只依赖它需要依赖的,从而达到它本身的修改不至于造成其它系统的非必要影响,反之亦然。

正交性

指一个模块提供的API中,多个方法之间是否有重复的功能。如果有重复功能,正交性就差。正交性高的模块更稳定,不会因为上层业务变化而被迫修改代码。好的API内部的多个方法之间不应该有任何重复功能,只实现正交的机制。

但实际开发中经常遇到拆分太细不便调用,可以封装出中间层的API调用底层原语API来实现常用模式供上层使用。对于中间层中的模块,对正交性的要求可以稍低一些。上层代码既可以直接调用正交的底层API,又可以调用中间层的API。

紧凑性

指一个模块提供的API中,公有方法总数必须很少,每个方法的参数也必须很少。《Unix编程艺术》上说一个模块不要超过7个方法,不然就很难理解。

“实质重于形式”原则

设计程序时,应当按照程序员使用时需要知道的知识(实质)来判断依赖关系及程度,而不应当按照机器编译或者执行代码时的引用关系(形式)

注意:需要知道的知识不代表程序员已经知道。

解耦

耦合的程度就是耦合度,也就是双方依赖的程度。降低耦合,而这个过程就叫做解耦和。

解耦就是把必要的耦合理顺,同时尽量减少不必要的耦合(这一句其实就是高内聚低耦合的通俗解释)。

目前设计模式存在的意义就是实现开发中在大型系统设计上的解耦工作。

  • 采用现有设计模式实现解耦,如事件驱动模式、观察者模式责任链模式等都可以达到解耦的目的;
  • 采用面向接口的方式编程,而不是用直接的类型引用,除非在最小内聚单元内部。但使用该方法解耦需要注意不要滥用接口。
  • 高内聚,往往会带来一定程度的低耦合度。高内聚决定了内部自行依赖,对外只提供必须的接口或消息对象,那么由此即可达成较低的耦合度。
  • 注解,以注解的方式,将方法,属性注入依赖,实现高扩展性。