第三部分:理论四
“解耦”为何如此重要?
- 软件设计与开发最重要的工作之一就是应对复杂性。
- 如果说重构是保证代码质量不至于腐化到无可救药地步的有效手段,那么利用解耦的方法对代码重构,就是保证代码不至于复杂到无法控制的有效手段。
- “高内聚、松耦合”是一个比较通用的设计思想,不仅可以指导细粒度的类和类之间关系的设计,还能指导粗粒度的系统、架构、模块的设计。
- 因为依赖关系简单,耦合小,修改代码不至于牵一发而动全身,代码改动比较集中,引入 bug 的风险也就减少了很多。
- “高内聚、松耦合”的代码可测试性也更加好,容易 mock 或者很少需要 mock 外部依赖的模块或者类。
代码是否需要“解耦”?
- 看修改代码会不会牵一发而动全身。
- 把模块与模块之间、类与类之间的依赖关系画出来,根据依赖关系图的复杂性来判断是否需要解耦重构。
如何给代码“解耦”?
封装与抽象
- 封装和抽象可以有效地隐藏实现的复杂性,隔离实现的易变性,给依赖的模块提供稳定且易用的抽象接口。
- 比如,Unix 系统提供的 open() 文件操作函数,我们通过将其封装成一个抽象的 open() 函数,能够有效控制代码复杂性的蔓延,将复杂性封装在局部代码中。我们在改动 open() 函数的底层实现的时候,并不需要改动依赖它的上层代码,也符合我们前面提到的“高内聚、松耦合”代码的评判标准。
中间层
- 引入中间层能简化模块或类之间的依赖关系。
- 在引入数据存储中间层之前,A、B、C 三个模块都要依赖内存一级缓存、Redis 二级缓存、DB 持久化存储三个模块。在引入中间层之后,三个模块只需要依赖数据存储一个模块即可。
- 我们在进行重构的时候,引入中间层可以起到过渡的作用,能够让开发和重构同步进行,不互相干扰:
- 第一阶段:引入一个中间层,包裹老的接口,提供新的接口定义。
- 第二阶段:新开发的代码依赖中间层提供的新接口。
- 第三阶段:将依赖老接口的代码改为调用新接口。
- 第四阶段:确保所有的代码都调用新接口之后,删除掉老的接口。
模块化
- 模块化是构建复杂系统常用的手段。对于一个大型复杂系统来说,没有人能掌控所有的细节。
- 不同的模块之间通过 API 来进行通信,每个模块之间耦合很小,每个小的团队聚焦于一个独立的高内聚模块来开发,最终像搭积木一样将各个模块组装起来,构建成一个超级复杂的系统。
- 合理地划分模块能有效地解耦代码,提高代码的可读性和可维护性。
- 模块化思想更加本质的东西就是分而治之。
其他设计思想和原则
- 单一职责原则
- 基于接口而非实现编程
- 依赖注入
- 多用组合少用继承
- 迪米特法则:不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。
posted @
2021-10-04 20:58
起床睡觉
阅读(
25)
评论()
编辑
收藏
举报