第三部分:理论四

第三部分:理论四

“解耦”为何如此重要?

  • 软件设计与开发最重要的工作之一就是应对复杂性。
  • 如果说重构是保证代码质量不至于腐化到无可救药地步的有效手段,那么利用解耦的方法对代码重构,就是保证代码不至于复杂到无法控制的有效手段。
  • “高内聚、松耦合”是一个比较通用的设计思想,不仅可以指导细粒度的类和类之间关系的设计,还能指导粗粒度的系统、架构、模块的设计。
  • 因为依赖关系简单,耦合小,修改代码不至于牵一发而动全身,代码改动比较集中,引入 bug 的风险也就减少了很多。
  • “高内聚、松耦合”的代码可测试性也更加好,容易 mock 或者很少需要 mock 外部依赖的模块或者类。

代码是否需要“解耦”?

  • 看修改代码会不会牵一发而动全身。
  • 把模块与模块之间、类与类之间的依赖关系画出来,根据依赖关系图的复杂性来判断是否需要解耦重构。

如何给代码“解耦”?

封装与抽象

  • 封装和抽象可以有效地隐藏实现的复杂性,隔离实现的易变性,给依赖的模块提供稳定且易用的抽象接口。
  • 比如,Unix 系统提供的 open() 文件操作函数,我们通过将其封装成一个抽象的 open() 函数,能够有效控制代码复杂性的蔓延,将复杂性封装在局部代码中。我们在改动 open() 函数的底层实现的时候,并不需要改动依赖它的上层代码,也符合我们前面提到的“高内聚、松耦合”代码的评判标准。

中间层

  • 引入中间层能简化模块或类之间的依赖关系。
  • 在引入数据存储中间层之前,A、B、C 三个模块都要依赖内存一级缓存、Redis 二级缓存、DB 持久化存储三个模块。在引入中间层之后,三个模块只需要依赖数据存储一个模块即可。
  • 我们在进行重构的时候,引入中间层可以起到过渡的作用,能够让开发和重构同步进行,不互相干扰:
    1. 第一阶段:引入一个中间层,包裹老的接口,提供新的接口定义。
    2. 第二阶段:新开发的代码依赖中间层提供的新接口。
    3. 第三阶段:将依赖老接口的代码改为调用新接口。
    4. 第四阶段:确保所有的代码都调用新接口之后,删除掉老的接口。

image

模块化

  • 模块化是构建复杂系统常用的手段。对于一个大型复杂系统来说,没有人能掌控所有的细节。
  • 不同的模块之间通过 API 来进行通信,每个模块之间耦合很小,每个小的团队聚焦于一个独立的高内聚模块来开发,最终像搭积木一样将各个模块组装起来,构建成一个超级复杂的系统。
  • 合理地划分模块能有效地解耦代码,提高代码的可读性和可维护性。
  • 模块化思想更加本质的东西就是分而治之。

其他设计思想和原则

  • 单一职责原则
  • 基于接口而非实现编程
  • 依赖注入
  • 多用组合少用继承
  • 迪米特法则:不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。
posted @ 2021-10-04 20:58  起床睡觉  阅读(25)  评论(0编辑  收藏  举报