Engineering
代码库设计
设计深层模块的共享词汇。适用于设计或改进模块接口、寻找深化机会、决定接口位置、使代码更可测试或更易被 AI 导航时。
代码库设计
设计深层模块:在小接口背后隐藏大量行为,放置在清晰的接口处,可通过该接口进行测试。
术语表
模块(Module) —— 任何具有接口和实现的东西。
接口(Interface) —— 调用者正确使用模块所需知道的一切:类型签名,以及不变量、排序约束、错误模式、所需配置和性能特征。
实现(Implementation) —— 模块内部的内容,即代码本体。
深度(Depth) —— 接口的杠杆效应:调用者(或测试)每学习一个单位接口所能驱动的行为量。
接口处(Seam) —— 可以在不修改该位置的情况下改变行为的地方;模块接口所处的位置。
适配器(Adapter) —— 在接口处满足接口的具体实现。
杠杆(Leverage) —— 调用者从深度中获得的:每学习一个单位接口就能获得更多能力。
局部性(Locality) —— 维护者从深度中获得的:变更、Bug、知识和验证都集中在一个地方。
深层与浅层
深层模块 = 小接口 + 大量实现。
浅层模块 = 大接口 + 少量实现(应避免)。
设计接口时,问自己:
- 能否减少方法数量?
- 能否简化参数?
- 能否将更多复杂性隐藏在内部?
原则
- 深度是接口的属性,而非实现的属性。
- 删除测试。 想象删除这个模块。如果复杂性消失了,说明它只是透传。如果复杂性在 N 个调用者中重新出现,说明它在发挥价值。
- 接口就是测试面。 调用者和测试跨越同一个接口处。
- 一个适配器意味着一个假设的接口处。两个适配器意味着一个真实的接口处。
为可测试性而设计
好的接口让测试变得自然:
- 接受依赖,而非创建依赖。
- 返回结果,而非产生副作用。
- 小的接口面。 更少的方法 = 更少的测试。