tactical-ddd
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTactical DDD — Rich Domain Modeling
战术DDD — 富领域建模
Workflow
工作流程
Determine the user's intent first:
| Intent | Phases to run |
|---|---|
| "validate / review / check / is this correct?" | Phase 1 + 2 only → report findings, ask before refactoring |
| "fix / refactor / improve / clean up" | Phase 1 + 2 + 3 |
| "how should I design / model this?" | Load reference.md directly |
首先确定用户的意图:
| 意图 | 执行阶段 |
|---|---|
| "验证 / 评审 / 检查 / 这样是否正确?" | 仅执行阶段1 + 2 → 报告发现结果,在重构前询问用户 |
| "修复 / 重构 / 优化 / 清理" | 执行阶段1 + 2 + 3 |
| "我该如何设计 / 建模这个?" | 直接加载[reference.md] |
Phase 1 — Detect
阶段1 — 检测
Load detection.md and scan the target code for anemia signals. Produce a severity score and list of affected classes.
加载[detection.md]并扫描目标代码,查找贫血模型信号。生成严重程度评分及受影响类别的列表。
Phase 2 — Assess
阶段2 — 评估
For each affected class, determine the correct building block:
| Has unique identity tracked over time? | Has invariants tying multiple objects? | → Building Block |
|---|---|---|
| Yes | — | Entity |
| No | — | Value Object |
| Yes (root) + children with shared invariants | Yes | Aggregate |
| Operation spans multiple Aggregates/doesn't belong to any | — | Domain Service |
Prefer Value Objects over Entities. Prefer small Aggregates over large ones.
If intent was validate/review: stop here. Report findings using the output format below. Ask "Would you like me to apply these fixes?" before proceeding.
针对每个受影响的类别,确定正确的构建块:
| 是否具有随时间跟踪的唯一标识? | 是否存在关联多个对象的不变量? | → 构建块 |
|---|---|---|
| 是 | — | Entity |
| 否 | — | Value Object |
| 是(根实体) + 具有共享不变量的子实体 | 是 | Aggregate |
| 操作跨越多个Aggregate/不属于任何Aggregate | — | Domain Service |
优先使用Value Object而非Entity。优先使用小型Aggregate而非大型Aggregate。
如果用户意图是验证/评审:在此停止。使用下方的输出格式报告发现结果。在继续前询问用户“是否需要我应用这些修复方案?”。
Phase 3 — Refactor
阶段3 — 重构
Load refactoring.md for step-by-step moves. Apply in this order:
- Replace setter chains with a single expressive method
- Move service logic into the Aggregate that owns it
- Add business guards at the top of each method
- Publish a Domain Event after each successful state change
- Replace primitive types with Value Objects
For deep pattern questions (boundary design, event modeling, service vs. entity decision), load reference.md.
加载[refactoring.md]获取分步重构步骤。按以下顺序执行:
- 用单一表达性方法替换链式setter调用
- 将服务逻辑迁移至拥有该逻辑的Aggregate中
- 在每个方法顶部添加业务校验逻辑
- 每次成功的状态变更后发布Domain Event
- 用Value Object替换原始类型
对于深层模式问题(边界设计、事件建模、服务与实体的选择决策),加载[reference.md]。
Quick Anemia Signals (scan first)
快速贫血信号(优先扫描)
public setX() / public setY() → behaviour should be encapsulated
service.doX(entity, ...) → logic likely belongs in entity
entity.setA(); entity.setB(); ... → setter chain = missing intent method
no domain methods beyond getters → pure data bagpublic setX() / public setY() → 行为应被封装
service.doX(entity, ...) → 逻辑可能属于实体
entity.setA(); entity.setB(); ... → 链式setter调用 = 缺少意图明确的方法
no domain methods beyond getters → 纯数据容器Golden Rules
黄金准则
- Behaviour with data — Objects own both state and the operations that change it
- Ubiquitous Language — Method names come from the domain, not CRUD (, not
commitTo)setStatus - Small Aggregates — Root + Value Objects by default; add child Entities only for true invariants
- One transaction = one Aggregate — Cross-Aggregate rules use eventual consistency via Domain Events
- Reference by ID — Never hold object references to other Aggregates
- Value Objects first — Use Entities only when individual identity is essential
- Domain Services sparingly — Excessive services → anemic model
- Protect invariants — The Aggregate is the last line of defence; never trust the caller
- 数据与行为绑定 — 对象同时拥有状态和修改状态的操作
- Ubiquitous Language — 方法名称源自业务领域,而非CRUD操作(例如使用而非
commitTo)setStatus - 小型Aggregate — 默认使用根实体 + Value Object;仅在存在真正的不变量时才添加子Entity
- 一个事务 = 一个Aggregate — 跨Aggregate的规则通过Domain Event实现最终一致性
- 通过ID引用 — 绝不持有其他Aggregate的对象引用
- 优先使用Value Object — 仅当个体标识至关重要时才使用Entity
- 谨慎使用Domain Service — 过多的Domain Service → 贫血模型
- 保护不变量 — Aggregate是最后一道防线;永远不要信任调用方
Output Format
输出格式
When reviewing code, report:
undefined评审代码时,按以下格式报告:
undefinedAnemia Diagnosis: <ClassName>
贫血模型诊断: <ClassName>
Severity: [None | Mild | Moderate | Severe]
Issues:
- <description of problem>
Recommended refactoring:
- <specific move from refactoring.md>
When refactoring, show a before/after diff for each class touched.严重程度: [无 | 轻度 | 中度 | 重度]
问题:
- <问题描述>
推荐重构方案:
- <来自refactoring.md的具体步骤>
重构时,展示每个被修改类的前后差异对比。