领域建模
在设计时主动构建并打磨项目的领域模型。这是*主动*的纪律:挑战术语、发明边界情况场景,并在术语和决策形成时立即写下词汇表和决策。(仅仅为词汇*阅读* CONTEXT.md 不属于此技能:那是一行习惯,任何技能都可以做到。此技能用于你在改变模型时,而不仅仅是消费它。)
文件结构
大多数仓库有一个单一上下文:
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
如果根目录存在 CONTEXT-MAP.md,则仓库有多个上下文。映射指向每个上下文所在位置:
/
├── CONTEXT-MAP.md
├── docs/
│ └── adr/ ← system-wide decisions
├── src/
│ ├── ordering/
│ │ ├── CONTEXT.md
│ │ └── docs/adr/ ← context-specific decisions
│ └── billing/
│ ├── CONTEXT.md
│ └── docs/adr/
懒惰地创建文件:只有在有内容可写时才创建。如果不存在 CONTEXT.md,则在第一个术语被解决时创建一个。如果不存在 docs/adr/,则在需要第一个 ADR 时创建它。
会话期间
针对词汇表进行挑战
当用户使用与 CONTEXT.md 中现有语言冲突的术语时,立即指出。“你的词汇表将 'cancellation' 定义为 X,但你似乎指的是 Y。到底是哪一个?”
打磨模糊语言
当用户使用含糊或过载的术语时,提出一个精确的规范术语。“你说的是 'account':你指的是 Customer 还是 User?它们是不同的东西。”
讨论具体场景
当讨论领域关系时,用具体场景进行压力测试。发明探测边界情况的场景,并迫使用户精确说明概念之间的边界。
与代码交叉引用
当用户陈述某物如何工作时,检查代码是否同意。如果你发现矛盾,把它暴露出来:“你的代码会取消整个 Orders,但你刚才说部分取消是可能的。哪一个是正确的?”
内联更新 CONTEXT.md
当术语被解决时,就在那里更新 CONTEXT.md。不要批量处理这些更新:在它们发生时捕获。使用 [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md) 中的格式。
CONTEXT.md 应完全不含实现细节。不要将 CONTEXT.md 当作规范、草稿纸或实现决策的存储库。它是词汇表,仅此而已。
谨慎提供 ADR
只有当以下三项都成立时,才提供创建 ADR:
- 难以逆转:以后改变主意的成本是有意义的
- 没有上下文时会令人惊讶:未来的读者会疑惑“他们为什么要这样做?”
- 真实权衡的结果:存在真正的替代方案,而你因特定原因选择了一个
如果缺少三项中的任何一项,跳过 ADR。使用 [ADR-FORMAT.md](./ADR-FORMAT.md) 中的格式。