防腐层、生命值模型与系列复盘
DDD 领域驱动设计 · 第 15/15 篇
上一篇:《COLA 应用架构与工业级脚手架》
开头:让代码腐烂得慢一些
互联网业务迭代快、人员流动大、多人协作风格不一——新仓库往往结构整洁,时间一长却难免变成「屎山」。DDD 与清晰的分层不能杜绝腐败,但能让腐烂来得慢一些。本篇收束 防腐层(ACL)、软件生命值隐喻,梳理微软 9 个微服务模式,并对全系列 15 篇做一次路线图复盘。
一、软件的生命值模型
Uncle Bob 在《代码整洁之道》里用三个词描述代码与变更的关系:
| 概念 | 含义 | 开发中的对应 |
|---|---|---|
| Hardware(硬件) | 创造后很难变更 | 数据库选型(MySQL → MongoDB 成本极高) |
| Software(软件) | 创造后可随时修改 | 业务代码应追求的目标 |
| Firmware(固件) | 强依赖某硬件的软件 | DAO 强依赖具体 DB 实现 |
固件会传播:应用服务若强依赖外部接口或 DAO,外部限制会让业务代码也变得难以变更——这就是软件的「固化」。
应对思路:
- 组内定期重构,偿还技术债
- 设计完善的应用架构,延缓腐败
- 保持简单,让各层级开发者都能快速上手
防腐层正是打破「固件传播」的关键手段之一。
二、九个微服务设计模式
2017 年微软 Azure CAT 团队在 Azure 架构中心发布 9 个微服务设计模式,帮助在微服务架构中有意识地选用成熟方案:

| 模式 | 作用 |
|---|---|
| Ambassador(外交官) | 语言无关地处理客户端连接任务:监控、日志、路由、TLS 安全 |
| Anti-corruption Layer(防腐层) | 介于新旧系统之间,确保新设计不受遗留系统限制 |
| Backends for Frontends | 为桌面/移动等不同客户端提供独立后端,避免单后端处理冲突请求 |
| Bulkhead(舱壁) | 隔离各工作负载的关键资源(连接池、内存、CPU),防止级联故障 |
| Gateway Aggregation | 聚合对多个微服务的请求,减少往返 |
| Gateway Offloading | 将 SSL、认证等横切能力卸载到网关 |
| Gateway Routing | 网关路由到后端服务 |
| Sidecar(边车) | 辅助组件独立容器/进程部署,提供隔离 |
| Strangler(绞杀者) | 逐步替换遗留系统,而非一次性推倒重来 |
以下重点展开防腐层——与 DDD 战术层、COLA Gateway 一脉相承。
三、防腐层(Anti-Corruption Layer)
Eric Evans 在《领域驱动设计》中提出 ACL。当系统依赖外部不合理的数据结构、API、协议或实现时,强依赖会导致内部被「腐蚀」。ACL 隔离外部与内部,外部怎么变,内部尽量不变。

ACL 介于新应用与旧/外系统之间,通过现有接口通信,几乎无需修改对方;本质是域映射——让第二个域的服务不被第一个域的概念污染。
3.1 ACL 能做什么
除简单调用封装外,ACL 还可承载:
| 能力 | 说明 |
|---|---|
| 适配器 | 外部数据/协议不符合内部规范,转化逻辑封装在 ACL |
| 缓存 | 高频、低频变更的外部依赖,缓存嵌入 ACL 降低侵入 |
| 兜底 | 外部不稳定时返回最近成功缓存或业务兜底数据 |
| 易于测试 | Facade 接口便于 Mock/Stub |
| 功能开关 | 在 ACL 配置启用/禁用或 mock 返回值,不影响核心业务 |
3.2 使用场景
适合:
- 渐进式迁移:旧系统往往是当前最赚钱的部分,不宜急于整体替换。包一层 ACL,可逐步替换功能而不影响现网
- 语义不同的多系统对接:如收银台对接支付宝、银行、信用卡,需将支付信息转为各三方格式
- 多组件共享外部依赖:抽奖平台各券种组件都需用户信息,在平台层建统一 ACL
不适合:新旧系统无重要语义差异时,ACL 可能是过度设计。
3.3 设计与实现要点
与 ddd-13 中 Application 层 ACL 规范一致:
- 返回值必须是本地 VO/DTO/基本类型
- 捕获外部异常,转本地异常;错误码不向上透传
- 按需返回字段,避免外部大 DTO 污染领域
COLA 中 Domain.gateway + Infra.gatewayimpl 即 ACL 的工业级落地;Repository 则是面向持久化的特殊 ACL。
四、全系列 15 篇复盘
本系列从「为什么要 DDD」走到「如何写进仓库」,可按四条线回顾:
4.1 入门与动机(第 1–3 篇)
- 01 DDD 是什么:历史、价值、本质收益
- 02 流程与贫血模型:Scrum 断层、事务脚本 vs 贫血/充血 MVC
- 03 SOLID 与 OO:架构基础、隐式业务显式化
takeaway:DDD 解决的是业务复杂度与模型失真,不是换一套名词。
4.2 战略设计(第 4–7 篇)
- 04 核心概念:宏观/微观概念、限界上下文直觉
- 05 微服务拆分:领域驱动而非数据驱动
- 06 战略建模:四色建模、用例分析、领域故事
- 07 通用语言与事件风暴:UL、Event Storming 落地步骤
takeaway:先划 BC、统一语言,再谈服务边界与协作。
4.3 战术与分层(第 8–13 篇)
- 08 分层与四种模型:失血/贫血/充血/胀血
- 09 Domain Primitive:三原则与重构步骤
- 10 六边形新应用:从 0 到 1 搭应用
- 11 Repository:模式与模型对象规范
- 12 领域层规范:聚合、副作用、领域事件
- 13 应用层与接口层:CQE、ACL、O&C
takeaway:Domain 承载规则,Application 编排用例,Interface 解耦协议。
4.4 落地实践(第 14–15 篇)
- 14 COLA 与脚手架:微服务内部设计、COLA 分层、CQE 流程
- 15 防腐层与复盘(本篇):ACL、9 模式、系列 checklist
五、系列实践 Checklist
落地一个新域或重构一块老代码时,可按此清单自检:
战略阶段
战术阶段
集成与演进
六、结语
DDD 不是银弹,而是一套让业务语义驱动架构演进的方法论。微服务提供部署与治理的物理边界,COLA 等脚手架把战术模式固化成日常可执行的目录与组件,防腐层则守住边界上下文不被外部「腐蚀」。
15 篇系列至此完结。若你正在接手一块流水账模块,建议从 划用例 → 写 CQE → 抽 Domain → 加 Gateway 四步开始,比一次性「全面 DDD 改造」更容易见到成效。
本篇小结
- 业务代码应是「软件」;DAO/外部强依赖会像「固件」一样传播僵化
- 微软 9 模式涵盖 ACL、BFF、舱壁、绞杀者等;ACL 适合迁移与异构集成
- 全系列:动机 → 战略建模 → 战术分层 → COLA/ACL 落地
- Checklist 可用于新项目启动或老系统重构前的自检