耦合与内聚。

耦合 VS 内聚

耦合

耦合是对coupling的中文翻译。而coupling是couple的变形,指a connection (like a clamp or vise) between two things so they move together。

存在一种连接在两事物之间,以至于这两事物相互影响。

在本文中,耦合可以是一个名词——耦合度的同义词,也可以作为形容词——耦合性的同义词。

不少书籍都告诉我们要追求高内聚(High Cohesion)及低耦合(Low Coupling)的软件?高内聚和低耦合可以给我们软件开发人员带来可读性、复用性、可维护性和易变更性。

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

事实上,在软件开发过程中,耦合的本质是假设

  1. 在设计软件过程,在业务级别上,对与其交互的业务的假设是什么?
  2. 它需要使用哪些具体技术,可否将这些具体技术隔离出去,以至于我可以低成本的更换实现,也就是减少对具体技术的假设。
  3. 在写代码时,方法级别上它是不是对其它方法的处理结果进行假设了?类级别的设计有什么假设?等等。

总的来说,就是找到软件开发过程中每个环节可能的假设,并问:如果这个假设并打破了,系统会受到什么影响?

以上,是传统意义上的低耦合。

我感觉上面这种概念很难理解。并且在写代码的时候,需要考虑很多的东西。

非常的复杂,可能,对于一个富有经验的老手来说,简单一点,但对于我来说,我很难在自己去编写代码的时候,考虑这么多的内容。

我在写代码的时候更多的是靠以下的概念。

我认为这是低耦合的一种变种。

下面有相关概念的变种。 -->>  依赖。

依赖 + 正交 + 紧凑

  1. 依赖
    依赖和耦合的最大区别在于,当我们说“A和B耦合”时,在字面含义中,A和B二者平等。然而,正确的模块关系根本不应该平等,而应该是单向依赖才对。所以我们应该说“A依赖B”,这样含义要清楚得多。A依赖B意味着,A模块可以调用B模块暴露的API,但B模块绝不允许调用A模块的API。
    单向依赖是红线,好的设计一定不会违反这条红线。
    只要程序员编写模块A时,需要知道模块B的存在,需要知道模块B提供哪些功能,A对B依赖就存在。
  2. 正交
    正交性是指一个模块提供的API中,多个方法之间是否有重复的功能。如果有重复功能,正交性就差。
    通常,正交性高的模块更稳定,不会因为上层业务变化而被迫修改代码。好的API内部的多个方法之间不应该有任何重复功能,只实现正交的机制。
    如果感觉拆得太细使用不便,应该在底层API之外包装出一层Helper、Utility组成的胶水层
    胶水层调用底层原语API来实现常用模式供上层使用。对于胶水层中的模块,对正交性的要求可以稍低一些。注意上层代码既可以直接调用正交的底层API,又可以调用胶水层的常用模式。
  3. 紧凑
    紧凑性是指一段程序提供的API中,公有方法总数必须很少,每个方法的参数也必须很少。
    《代码大全》上说一个类应该将参数的类型限制为 7 个。多了,就需要考虑这个类的作用,功能,然后拆分。

通过这三个指标,将一段程序给量化。

正交: 方便程序的复用,并减少对程序本身单一功能的污染

依赖:理解每一段代码的功能与另一端代码功能之间的关系。可以帮助这一段代码的整体逻辑更加的清楚。

紧凑:是为了方便理解这个类的功能。

依赖注入 DI + 控制反转 IOC

控制反转 : 
a 依赖 b, 但 a 不控制 b 的创建和销毁。交由第三方控制。
依赖注入 :
a 依赖 b, 必然使用 b 的 instance。使用的方法有三种:

1. 通过 a 的接口传入
2. 通过 a 的构造传入
3. 通过设置 a 的属性将 b 传入

当时,在面试的时候,就问我这个问题, 这两个名词作用就是减少耦合。

一段生动形象的比喻是这样的。

正常的造一辆车,是先造轮子,然后底盘,然后外壳,发动机,最后建成一辆车。

但是如果轮子换了,上面的底盘,外壳,发动机可能都要改变,因为这整个车都是依赖于底层的轮子建造起来的。

而 DI + IOC 的逻辑是,

先有一辆车,然后传入发动机,发动机传入外壳,外壳传入底盘,底盘传入轮子。、

这样一来,即便轮子换了,只需要改变轮子的形状,样式,然后传入底盘就可以了,完全影响不到上层模块的构建。

这样上层模块(车)就和下层模块(轮子)解耦了。

结语

以上就是我理解的耦合,很浅显,还有很多要学习的地方。

并且只有不断的实践才能帮助自己真正理解这个概念。

代码之路,才刚刚启程~~

0%