分解、模块与接口
复习
- 需求与边界:先弄清要做什么、不做什么
- 抽象:加一层,把复杂藏起来
- 函数:把一段工作命名、封装起来
TL;DR
- 把大程序切成可独立理解、替换的模块
- 模块之间通过接口交流
- 好的分解能降低耦合、便于并行开发
- 这和前面反复出现的“分层与封装”一脉相承
正文
需求清楚了,接下来要面对的是“怎么把它搭出来”。一个稍大的软件,动辄成千上万行代码,直接从头写到尾,是没法维护的。办法还是那个老朋友:分解。
切成人能理解的小块
把一个大程序,切成若干个模块(module):每个模块负责一块相对独立的职责。
切分的目标有两条,常被概括成一句话:
- 高内聚(high cohesion):一个模块内部做的事,应该彼此相关、围绕一个明确的职责
- 低耦合(low coupling):模块之间尽量少依赖、少纠缠
高内聚让一个模块“专注”,容易理解;低耦合让改动一个模块时,不容易牵连别的模块,容易维护。这两条,是模块划分好不好的重要标准。
接口:模块之间怎么说话
模块之间总不能互相看透对方的内部。它们通过接口(interface)交流:我对外承诺能提供什么,你需要我做什么,就按这个来。
这正是我们前面讲过无数次的思想:接口与实现分离。只要接口不变,一个模块的内部怎么改,都不影响其他模块。于是:
- 不同的人可以并行开发不同的模块(只要接口先定好)
- 一个模块的实现可以被替换,只要还遵守原接口
- 出了问题,可以限定在某个模块内部去查
又一次呼应主线
分解、模块、接口,说到底还是那几件事:把复杂问题拆小,用清晰的边界隔开,再用稳定的接口连接。
从逻辑门到芯片、从函数到操作系统、从协议分层到编译器阶段——“分层、封装、接口”这条主线,贯穿了整部教程。 软件构造不过是把它用在了“代码组织”上而已。
思考题 1
为什么要把大程序分解成模块?
思考题 2
“高内聚、低耦合”大概是什么意思?
小结
知识点
- 模块化把大程序切成独立的职责单元
- 高内聚指模块内部职责集中
- 低耦合指模块之间依赖少
- 模块通过接口交流,接口稳定则内部可替换
参考资料
- Wikipedia(zh):模块化编程:把程序划分为独立模块
- Wikipedia(zh):耦合性 (计算机科学):模块之间依赖的程度
思考题答案(仅供参考)
思考题 1
因为一个稍大的程序直接从头写到尾难以理解和维护。分解成模块后,每块职责相对独立、便于单独理解和测试;接口稳定时还能并行开发和替换实现,出问题也更容易定位。
思考题 2
高内聚指一个模块内部的功能彼此相关、围绕一个明确职责,显得专注;低耦合指模块之间尽量少相互依赖。前者让模块好理解,后者让改动不易牵连他处,两者共同决定了模块划分的质量。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪