技能domain-modeling
D

domain-modeling

构建并完善项目的领域模型。用于讨论代码库术语、编写或编辑 CONTEXT.md,或记录或编辑 ADR。

Domain Modeling — 边设计边打磨项目的领域模型

技能概述

Domain Modeling 是一个主动式的领域建模技能:在讨论代码术语、编写 CONTEXT.md 或记录 ADR 的过程中,帮你挑战含糊用词、推演边界场景,并把敲定的术语和决策当场写进仓库。

适用场景

  1. 团队对同一个词的理解不一致时 有人说的"账户"指 Customer,有人指 User;有人说的"取消"是整个订单取消,有人以为是部分取消。技能会立刻指出这种冲突,要求你选一个,并把结论固化到术语表里,而不是让它继续在口头传播中漂移。

  2. 需要为项目建立或更新 CONTEXT.md 时 当第一个术语被敲定、或仓库里根本没有术语表时,技能会按约定格式创建 CONTEXT.md;已有 CONTEXT-MAP.md 的多上下文仓库,它会写到对应上下文的目录下。它是一条条增量追加的,不会攒到最后批量生成。

  3. 记录或修订架构决策(ADR)时 当你做了一个"以后很难反悔、且后人会问为什么"的选择——比如事件溯源、写入模型选 Postgres——技能会判断它是否值得一条 ADR,值得才写,不值得就跳过,避免决策日志被稀释成一堆无意义的记录。

核心功能

  1. 对照术语表挑战用词 你在对话里用了一个与 CONTEXT.md 已有定义冲突的词,技能会当场叫停:"你的术语表把'取消'定义为 X,但你现在的意思像是 Y,到底以哪个为准?"它不替你决定,但绝不让冲突悄悄溜过去。

  2. 把模糊表达磨成精确的规范术语 遇到"账户""订单状态""同步"这类被重载的词,技能会提出一个唯一的规范名称,并逼你说清它和相邻概念的分界在哪。判断标准很实在:如果一段话里必须靠上下文才能猜出这个词指什么,它就还不够精确。

  3. 用具体场景反推概念边界 讨论领域关系时,技能会主动虚构边界场景来压测你的模型——"如果用户只取消了三件商品中的一件,Order 的状态是什么?"这些场景不是为了完备性,而是为了让你在代价还很低的当下,先撞上那些含混的地方。

  4. 核对代码是否真的和说法一致 你描述了某种行为,技能会去代码里验证。发现矛盾就直接摆到台面上:"你的代码取消的是整个 Order,但你刚说支持部分取消,哪个才是对的?"文档和实现不一致这件事,早一天发现便宜一天。

  5. 当场更新 CONTEXT.md,不攒批 术语一敲定就写进去,格式遵循技能自带的 CONTEXT-FORMAT.mdCONTEXT.md 是纯术语表——不是需求文档,不是草稿纸,也不是实现决策的存放处,这一点技能会严格守住。

  6. 克制地提议 ADR 只有当三个条件同时成立才建议写 ADR:改变主意的代价足够高、后人看到会疑惑"当初为什么这么做"、且确实是权衡了真备选方案后的选择。缺任何一条,技能就不提议。

常见问题

什么是领域建模?它和画 ER 图、写需求文档有什么不一样?

领域建模处理的是概念和语言,不是数据结构,也不是功能清单。ER 图回答"数据怎么存",需求文档回答"系统要做什么",领域建模回答的是"我们说的这个词到底指什么、它和相邻概念的分界线在哪"。它的产出是一份大家共用、且代码也遵守的词汇表。也正因为如此,CONTEXT.md 里必须完全不含实现细节——一旦混进表结构或接口设计,它就不再是术语表了。

CONTEXT.md 里应该写什么、不该写什么?

写:术语的规范名称、它的准确定义、它不是什么(边界)、以及它和其他术语的关系。不写:数据库字段、API 设计、框架选型、待办事项、实现思路。一个简单自检方式——如果你写的那句话在换一套技术栈后就不再成立,那它就不属于 CONTEXT.md

什么样的决策才值得写一条 ADR?

同时满足三条才值得:改变代价高(事后反悔要付出实质成本)、后人会困惑(没有背景的人会问"为什么不用更常见的做法")、是真权衡(确实存在合理备选,你是出于具体理由选了这一个)。三条缺一就不要写。按这个标准,"我们把变量命名为 camelCase"不值得 ADR;"订单写入模型用 Postgres 而不是事件溯源"值得。

项目分多个模块时,术语表要建几份?

看有没有 CONTEXT-MAP.md。根目录有这份地图文件,说明项目是多上下文的,每个上下文在自己的目录下各有一份 CONTEXT.md,上下文专属的 ADR 也放在各自的 docs/adr/;跨系统的全局决策才放在根目录的 docs/adr/。没有地图文件就是单上下文,根目录一份 CONTEXT.md 即可。这些文件都是按需创建的——有第一个术语要记时才建 CONTEXT.md,有第一条 ADR 要写时才建 docs/adr/

代码实现和术语表描述冲突了,以哪个为准?

技能不会默认哪边优先,而是把矛盾摊开让你判断:可能是代码有 bug,也可能是术语表的定义已经过时。关键在于必须选一个并让两边重新对齐——最糟的状态是文档写一套、代码做一套,然后所有人都学会不再信任文档。技能每次发现这类分歧都会主动报告,不会默默绕过。

这个技能会主动改我的代码吗?

不会。它的写入范围限于领域模型文档——CONTEXT.mdCONTEXT-MAP.mddocs/adr/ 下的 ADR。它读代码是为了核对你的说法是否和实现一致,但不会为了让代码符合术语表而直接改代码;发现不一致时它会告诉你,由你决定改哪边。

小项目或者个人项目也需要领域建模吗?

需要,但规模小得多。判据不是项目大小,而是这个词会不会被反复使用并产生歧义。个人项目里 CONTEXT.md 可能只有五行,一条 ADR 都没有,这完全正常。反过来说,小项目里一个含混的核心概念——比如"用户"和"账号"混着用——带来的返工成本,往往比大项目还高,因为早期没人会去纠正它。

它和"读一下 CONTEXT.md 了解项目词汇"有什么区别?

这是两件不同的事。随手查一下术语表拿词汇,任何技能都能做,那只是消费已有的模型。Domain Modeling 是改变模型的那个技能:挑战用词、虚构边界场景、把新结论写下来。当你只是想知道"这个项目里 Order 指什么"时,不需要它;当你准备重新定义 Order 的边界时,才需要。