ARC 4接入真实业务工程第 15–18 章

第 15 章 —— 通过领域适配器隔离 DSM 细节

本章目标: 本章完成后,开发者能够用领域端口封装 DSM 三类 typed handles,把 locator、生命周期和失败翻译集中在适配器边界内。

学习目标

  1. 识别 DSM API 泄漏进业务层的维护代价。
  2. 设计只使用业务语言的 FulfillmentCoordination 端口。
  3. 把 Register、Lease、CRDT handle 与 locator 集中到 composition root。
  4. 分开验证领域决策和真实 Runtime 行为。

前置条件

案例进度

前三篇直接操作集合是为了学习语义。现在履约服务要进入真实工程:业务用例只说「发布路由」「领取分片」「记录请求」,不再知道 shared/gateway/route-hintsLeaseAcquireOptions

业务端口拥有语言,适配器拥有技术细节

领域端口与 DSM 适配器边界

书籍示例定义的端口很小:

public interface FulfillmentCoordination {
    void publishRoute(String serviceKey, String address);
    Optional<String> routeFor(String serviceKey);
    ShardClaim claimShard(String shardId);
    long incrementRequestCount();
}

端口不返回 DsmRegisterLeaseSnapshotPnCounterStateCollectionLocator。业务层因此能用 fake 直接测试;DSM 适配器负责把结果翻译成 ShardClaim(granted, uncertain, fencingToken, reason)

Composition root 是唯一装配点

DsmFulfillmentModule 集中拥有:

这不是为了隐藏所有 DSM 概念。locator 与 schema 仍是重要合同,只是由适配器拥有,而不是散落到 controller、service 和 job 中。

失败翻译不能抹掉不确定性

Lease acquire 有 granteduncertain、snapshot 和 reason。适配器若只返回 boolean,调用方无法区分明确拒绝与结果不确定。领域结果应保留业务决策实际需要的信息,同时阻止调用方任意操作底层 handle。

同样,fencing token 需要穿过端口进入受保护的下游写入;把 token 藏掉会让第 7 章的安全边界失效。示例当前返回 token,但没有实现真实下游 guard,因此验收卡明确不声称已完成外部 fencing。

两类测试,各自只证明一层

示例有两个测试:

  1. RecordingCoordination 验证 FulfillmentService 只依赖领域端口。这是 E1。
  2. 用真实 DsmRuntime 和三类集合验证适配器。这是单进程 E2。

如果只写第二类测试,业务决策和 DSM 装配会粘在一起;如果只写第一类,fake 全绿也不能证明真实 spec、codec 或 Lease 能运行。

反例与故障注入

实验

cd examples/order-fulfillment-control-plane
mvn clean test

阅读 port-contract.json,确认每个业务动作都有领域输入、领域输出、DSM handle 和未被适配器承担的外部责任。

实验验收卡

字段 内容
运行命令 cd examples/order-fulfillment-control-plane && mvn clean test
输入或故障 fake 端口;真实单节点 Runtime;三类 typed handles
可观察结果 领域服务不导入 DSM 类型;真实适配器完成路由、租约与计数操作
证据等级 E1 领域单元测试 + E2 单进程 Runtime 行为
本实验未证明 多节点传播、repair、真实网络、下游 fencing 或生产装配

回顾

下一步

第 16 章把手工 composition root 切换为 Spring Boot 属性和条件 bean,并验证实际上下文能启动。

证据链接