把架构约束写成自动检查
架构适应度函数指的是把对架构的期望写成可自动执行的检查:依赖方向、模块边界、性能预算、接口兼容性等。它们与单元测试同级运行在流水线里,随架构决策一起演进,持续验证结构没有在迭代中走样。它的作用是把口头约定变成有反馈的约束——约束只有能被自动发现违反,才可能长期成立。
常见形态
| 依赖检查 | 核心域不得依赖具体框架或外部实现 |
|---|---|
| 边界检查 | 模块之间不存在循环依赖与跨层调用 |
| 性能基准 | 关键接口响应时间或吞吐不回归 |
| 契约测试 | 公共接口保持向后兼容 |
| 位置 | CI 流水线,与单元测试同级执行 |
典型使用场景
- 分层架构落地:用依赖检查阻止上层直接调用底层实现细节
- 多模块仓库:检查模块间不存在循环依赖,防止依赖方向被逐步侵蚀
- 性能敏感服务:把关键路径的响应时间基准纳入流水线,回归即失败
- 对外接口演进:用契约测试确认新增字段不破坏既有调用方
- 架构决策记录落地:每次决策后补一条对应的检查,让决策可被验证
示例清单
示例清单
# 每一条对应一个可自动判断的断言
- 核心域不得依赖 web 框架(import 规则检查)
- 模块之间无循环依赖(依赖图分析)
- API 响应时间基准不回归(基准测试)
- 公共接口向后兼容(契约测试)
- 领域层不得直接访问数据库驱动约束与检查方式
| 期望 | 检查手段 | 失败时的动作 |
|---|---|---|
| 依赖方向正确 | 静态导入分析 | 定位违规引用并调整层次 |
| 无循环依赖 | 依赖图环检测 | 抽出接口或调整归属 |
| 性能不回归 | 基准测试与阈值比较 | 查看本次改动,必要时回滚 |
| 接口兼容 | 契约测试比对旧版本 | 改用兼容方式演进或升版本 |
| 边界不被绕过 | 架构规则脚本 | 补充例外说明或重构调用点 |
适应度函数要少而关键:每条检查都有维护成本,写得过多过细会让流水线变慢、误报增多,最后被整体禁用。优先覆盖那些一旦被违反就很难回头的约束。
例外要有登记机制:允许的违反必须写明原因与到期时间,否则例外会逐渐变成新的事实标准,检查形同虚设。
落地检查清单
- 每条检查对应一条明确的架构期望
- 检查能在流水线中稳定运行,耗时可控
- 违规信息包含位置与修复方向
- 例外清单有人维护,并有到期复核