限界上下文
限界上下文规定一套业务模型的适用范围。本文讲解领域划分、统一语言和上下文协作。
1. 面试核心
先记住这几条,再读正文- 子域与上下文。 子域划分业务问题,限界上下文划分模型的适用范围。卡 · 综合题
- 统一语言。 统一语言让领域专家与开发者在同一上下文内使用含义一致的术语。术语在不同上下文含义不同,是识别模型边界的线索。
- 模型独立。 同一客户 ID 可以跨上下文复用,各上下文保留自己的模型。
- 防腐层。 防腐层转换外部语义,避免外部模型渗入本地规则。卡 · 防腐层与语义转换
2. 领域与子域
领域是软件需要处理的业务范围。电商可分为商品、交易、库存和履约等子域。子域描述业务问题,上下文描述解决问题的模型边界。
核心子域承载业务差异,值得投入专门建模。支撑子域帮助核心业务运行。通用子域可评估成熟方案,例如身份认证。
简单 CRUD 可以直接使用事务脚本。规则复杂、概念易混淆时,领域建模的收益更大。
3. 限界上下文
“客户”在不同环节具有不同模型:
- 会员模型记录等级、积分和权益。
- 订单模型记录购买人 ID 和下单资格。
- 结算模型记录签约主体和账期。
这些模型可共享身份标识,但分别维护字段和规则。共用一个全局 Customer 会让业务差异变成条件分支。
限界上下文可以先实现为模块。独立部署的条件见微服务架构。
4. 统一语言
统一语言是业务与开发共同使用的词汇。它应出现在需求、验收条件、类名和接口中。日志、错误码与运行手册也使用相同名称。
业务说“确认订单”,代码可以提供 confirm()。方法内检查状态和确认条件。updateStatus(3) 则隐藏了动作含义。
不同上下文可对同一术语作不同定义。跨边界时通过上下文名称和契约区分含义。
5. 边界识别
沿完整业务流程检查五类信号:
- 领域专家负责解释哪些规则。
- 哪些代码因同一个需求一起修改。
- 哪些状态需要原子维护。
- 同一术语在哪里改变含义。
- 谁决定数据和接口的演进。
共同事务是边界信号之一。一个上下文仍可包含多个独立聚合。边界应随真实需求和变化范围持续校准。
6. 上下文之间的协作
上下文图记录依赖方向和集成方式。上游可发布稳定 API 或业务事件。下游按契约消费,也可用防腐层转换模型。
共享内核让双方共用一小段模型。共享范围越大,变更越依赖共同协调。契约需明确字段含义、版本和失败语义。
6.1 防腐层与语义转换
防腐层把外部模型转换为本地模型。例如,旧系统的 status=2 表示款项已授权。新系统应映射为“已授权”,并保留待扣款状态。若直接映射成“已支付”,履约就会提前。
转换应覆盖单位、状态和错误含义。无法识别的状态进入异常处理。领域规则仍由本地模型负责。
防腐层可作为进程内适配器,也可独立部署。独立部署后,它会增加延迟和运维成本。契约测试要覆盖旧接口的语义变化。
7. 订单协作示例
订单上下文判断取消条件并保存结果。库存收到取消事件后释放预占。支付判断退款或撤销授权。会员按最终结果调整积分。
对订单而言,取消是受状态机约束的命令。对其他上下文而言,取消结果是后续工作的输入。各方通过契约协作,分别维护自己的模型。
8. 常见问题
8.1 领域服务与应用服务
领域服务承载不自然归属单个实体的业务规则。应用服务负责用例编排、事务和鉴权。简单查询无需为此创建空壳对象。
8.2 数据所有权与物理数据库
上下文拥有数据定义和写入权。多个上下文可共用数据库实例。表的写入入口和迁移责任仍需分开。
9 · 面试题卡片
9.1 如何理解 DDD,项目中怎样识别限界上下文
出现公司:暂无已核验的公开来源(本站自测)
题型:综合题
考察重点
- 领域、子域、限界上下文和统一语言之间的关系。
- 业务边界与服务部署边界的区别。
- 如何用规则、变化、一致性和团队责任验证边界。
参考回答
DDD 用业务语言表达模型和规则。
限界上下文规定模型在哪个范围内成立。识别边界要结合术语含义、规则归属和共同变化。数据所有权与团队责任也是重要证据。
上下文内部使用统一语言。跨上下文通过 API、事件或防腐层交换语义。模型边界可以先落在模块中。是否拆成服务,取决于独立部署和隔离收益。
9.2 防腐层除了转换字段,还需要处理哪些问题?
出现公司:暂无已核验的公开来源(本站自测)
考察重点:状态语义、单位和错误映射。
相关内容:防腐层与语义转换。
参考回答
防腐层需要转换业务语义。
旧系统的支付授权应映射为“已授权”。把它当作“已支付”会提前触发履约。金额单位、错误码和未知状态也需明确映射。契约测试负责发现这些语义变化。