10k

设计模式之美-课程笔记20-规范与重构4

理论四:如何通过封装、抽象、模块化、中间层等解耦代码?

大型重构的好手段: 解耦。实现高内聚,低耦合。

  • 解耦为何如此重要
  • 如何判定代码是否需要解耦
  • 如何给代码解耦

解耦为何重要

  1. 控制代码复杂度。
  2. 高内聚、松耦合可以让我们聚焦在一个类或者模块中,不需要太多了解其他模块或者类的代码。代码阅读性相对好;而且耦合低了代表着依赖少了,在修改的时候需要涉及到的模块就少了,代码的可维护性也相对好;同时可测试性也好,因为解耦之后我们对于其他模块只需要mock即可。

代码是否需要“解耦”

  1. 一个方法:在阅读的时候将模块之间、类之间的依赖关系画出来,根据复杂度来判断。

如何给代码解耦

1. 封装与抽象

  1. 封装和抽象可以隐藏系统的复杂性,隔离实现的易变性,提供稳定且易用的接口。
  2. 比如Unix系统提供的open()文件操作函数,底层逻辑设计权限控制、并发控制、物理存储等,但是表面使用起来很简单。通过封装可以有效控制复杂代码的蔓延。而且open函数基于抽象而非实现来定义,我们改动的时候也不需要改动依赖他的上层代码。

2. 中间层

  1. 引入中间层能够简化模块或者类之间的依赖关系。例子如下:

img

  1. 在重构时,引入中间层可以起到过渡作用,让开发和重构同时进行。比如某个接口有问题需要修改定义,同时调用它的代码都要改动,如果新开发的代码也用到这里,那就冲突了。我们可以按照如下步骤执行:
    1. 第一阶段:引入一个中间层,包裹老的接口,提供新的接口定义。
    2. 第二阶段:新开发的代码依赖中间层提供的新接口。
    3. 第三阶段:将依赖老接口的代码改为调用新接口。
    4. 第四阶段:确保所有代码都调用新接口后,删掉老接口。

3. 模块化

  1. 模块化,不同的模块之间通过API通信,模块之间耦合很小。
  2. 宽泛来讲,模块化思想到处都有:微服务、lib库,系统内部模块划分等。

4. 其他的设计思想和原则

  • 单一职责原则:模块或者类小而单一而非大而全。
  • 基于接口而非实现编程:通过接口这个中间层,隔离变化和具体实现。
  • 依赖注入:虽然不能将两个类解耦为无依赖关系,但是可以做到热插拔替换。

  • 多用组合少用继承:继承深度与复杂度让耦合加深。

  • 迪米特法则:不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。从定义上,我们明显可以看出,这条原则的目的就是为了实现代码的松耦合。
Thoughts? Leave a comment