防腐层

防腐层用于隔离外部模型与内部领域模型污染的模式说明

#status / growing #type / concept #tech / dev

防腐层 Anti-Corruption Layer (ACL)

一句话定义

防腐层是 DDD 中的一个适配层,位于自己的限界上下文与外部系统之间,负责将外部模型翻译为内部领域模型,防止外部概念污染核心域。

核心机制 / 工作原理

为什么需要防腐层

  • 遗留系统集成 — 老系统的数据模型往往混乱、过时,直接暴露给新系统会污染新领域模型
  • 第三方 API — 外部服务的模型随时可能变化,ACL 提供隔离屏障
  • 限界上下文边界 — 不同团队维护的上下文有不同的领域语言,ACL 负责翻译

工作原理

内部领域模型  <-->  防腐层 (ACL)  <-->  外部系统模型
  Order              Translator          LegacyOrderDTO

ACL 内部包含:

  1. Facade — 简化外部系统的复杂接口
  2. Adapter — 调用外部系统的 API
  3. Translator — 将外部模型转换为内部领域对象

数据流:内部调用 ACL -> ACL 通过 Adapter 调用外部系统 -> Translator 将返回值转为内部模型 -> 返回给内部调用方。

最小例子

// 外部遗留支付系统返回的结构
public class LegacyPaymentResponse {
    public int status_code;      // 1=成功, 0=失败
    public String txn_id;
    public double amount_cents;  // 以分为单位
}

// 我们的领域模型
public class PaymentResult {
    PaymentStatus status;        // SUCCESS, FAILED
    String transactionId;
    Money amount;                // 包含币种的金额对象
}

// 防腐层 —— 翻译器
public class LegacyPaymentACL {
    private final LegacyPaymentClient client;

    public PaymentResult charge(Order order) {
        LegacyPaymentResponse resp = client.pay(
            order.getAmount().getCents(),
            order.getPaymentRef()
        );
        // 翻译:外部模型 -> 内部模型
        return new PaymentResult(
            resp.status_code == 1 ? PaymentStatus.SUCCESS : PaymentStatus.FAILED,
            resp.txn_id,
            Money.fromCents(resp.amount_cents)
        );
    }
}

核心域代码只依赖 PaymentResult,完全不知道 LegacyPaymentResponse 的存在。

边界与常见误解

  • “ACL 只是做数据转换” — 不只是转换。ACL 封装了外部系统的协议、调用方式、错误处理,使核心域完全不感知外部系统的存在。
  • “所有外部调用都需要 ACL” — 不是。如果外部系统的模型与你的领域模型高度一致,直接集成更简单。ACL 用于模型差异大外部系统不可控的场景。
  • ACL vs API Gateway — API Gateway 是入口层(面向客户端),ACL 是出口层(面向外部服务),方向相反。
  • ACL 会增加延迟吗 — 多一层调用确实有微量开销,但可忽略。价值在于隔离和可维护性。
  • ACL 放在哪里 — 通常放在防腐层自己的模块/包中,作为限界上下文的一部分,而不是独立服务。

anti-corruption-layer-usage

创建于 2026/1/27 更新于 2026/5/27