二〇二五年三月的一个深夜,我盯着屏幕上 Claude Code 生成的代码,整整沉默了二十分钟。不是因为代码太烂,恰恰相反,它生成的是一个标准的、教科书式的领域驱动设计分层结构:聚合根、值对象、领域服务、仓储接口,一应俱全。但问题是,它把合同计费规则写成了贫血模型,把一条本该在领域服务中承载的复杂业务逻辑,硬生生塞进了一个名为 ContractEntity 的 POJO 里,外加一堆 getter 和 setter。
那一瞬间我才意识到:我一直以来都在用生成普通 CRUD 代码的思维去驾驭 Claude Code,而它回馈给我的,正是我对领域驱动设计理解的真实映射。
市面上关于“用 AI 生成 DDD 代码”的讨论,九成以上都围绕着 Prompt 技巧、脚手架搭建、代码规范检查展开。但我在这条路上摸索了四个月之后,得出了一个和主流叙事不太一样的结论:Claude Code 不是一个代码生成器,它更像一面镜子,忠实地映射出你对业务逻辑理解的深度和模糊程度。你有多懂领域驱动设计,它就能生成多高质量的 DDD 代码;你对业务理解有盲区,它也一丝不苟地把这些盲区暴露在你的眼前。
这篇文章不会教你“三分钟用 AI 生成完整 DDD 项目”之类的速成技巧。恰恰相反,我会从一个资深后端架构师的第一视角出发,复盘我在三个真实项目中用 Claude Code 做领域驱动设计代码生成的完整历程:一次失败的尝试、一次扭转认知的突破、以及一次接近理想状态的“人机对话式建模”实践,三个阶段的对比数据、Prompt 演进策略、以及我踩过的那些坑,全部原原本本地摊给你看。
一、核心结论:先把话说在前头
在展开复盘之前,我想先把过去四个月反复试错后沉淀下来的六个核心判断放在这里。这些判断不是阅读某篇论文得出的推断,而是我在合同管理、佣金分账、理赔风控三个真实业务系统中,用 Claude Code 做了超过 200 轮对话之后,基于自己亲手跑出来的结果做的总结。
判断一:AI 生成的 DDD 代码质量,受限于 Prompter 本人的领域建模能力。
这是所有结论中最重要的一条,也是我这篇文章反复要论证的核心命题。四个月前我第一次用 Claude Code 生成 DDD 代码时,我得到的是一堆形式正确但毫无业务灵魂的贫血模型。四个月后的今天,当我能够清晰地向它描述合同计费规则的来龙去脉、聚合根之间的不变性约束、领域事件触发的上下游因果链条时,它生成的代码质量已经接近我们团队里三年经验的 DDD 实践者的水平。工具没变,变的是我向它描述业务的方式,而这背后,是我自己对业务逻辑的理解在不断加深。
判断二:Claude Code 在战术 DDD(Tactical DDD)层面的表现远超战略 DDD(Strategic DDD)层面。
这是我自己踩过的最大陷阱。战略 DDD 关注的是限界上下文划分、上下文映射、事件风暴,这些活动需要的是对业务全局的宏观把握、对组织结构和技术债务的深度理解,而这些信息几乎不可能通过一次性的 Prompt 完整传达给 AI。Claude Code 最擅长的是在限界上下文已经明确划定之后,帮你把聚合根、实体、值对象、领域服务、领域事件的代码骨架高质量地生成出来。但如果你指望它帮你做限界上下文划分,那你大概率会得到一个只有单一上下文、把所有逻辑揉在一起的“大泥球”。
判断三:好的 Prompt 不是“指令”,而是一种“对话”,你不是在给 AI 下达编码指令,而是在向它解释你的业务。
这是我在第二个项目中完成的认知切换。最初的失败尝试中,我的 Prompt 写的是:“请生成一个合同领域聚合根”。这句话和所有你不想要的贫血模型之间,只隔了一层窗户纸。后来我学会了这样问:“在这个合同场景中,计费规则的变化会影响到合同的状态流转吗?如果是,哪些领域事件应该在计费规则变更时被触发?”当我把提问方式从“下指令”切换成“解释业务并请求验证”时,Claude Code 的产出发生了质的飞跃。
判断四:Claude Code 对领域服务(Domain Service)的建模能力明显弱于对实体(Entity)和值对象(Value Object)的建模。
这是我在三个项目里反复验证的一个现象。Claude Code 在生成 Entity 和 Value Object 时非常稳定,字段映射、值校验、不变性保障都做得相当不错。但一旦涉及到跨聚合的领域服务、或者需要依赖外部防腐层接口的领域服务时,它的输出质量就会出现明显波动,有时会把领域服务退化成应用服务,有时会把本该属于领域服务的逻辑错误地塞进聚合根内部。这背后的原因我猜测是:领域服务承载的是业务的核心流程编排逻辑,而这个“流程”本身需要更大量的上下文才能被准确理解。
判断五:Claude Code 目前最实际的价值不是“替代编码”,而是“重新理解业务”。
这句话可能是整篇文章里最能体现我独特视角的一个判断。在做了四个月的实践之后,我认为 Claude Code 最大的价值并不在于提升了多少编码效率,虽然效率提升确实是显著的,而在于 它让我被迫重新审视自己对业务的理解是否足够清晰。当你向 AI 描述一个业务流程时,你不得不把它拆解成极其精确的语言,而在这个拆解过程中,你往往会发现自己原来有很多“以为懂了但其实没真懂”的灰色地带。
判断六:AI 在 DDD 场景下的上限是人,下限也是人。
如果你对 DDD 的理解停留在“按表建类、写几个 Repository 接口”的层面,那 Claude Code 给你的就是一套花架子。如果你真正理解了领域驱动设计的底层思想,限界上下文、聚合边界、领域事件、统一语言,那 Claude Code 就是一个精准而不知疲倦的实现伙伴。它不会让你变得比你自己更懂业务,但它会让你的业务理解以更高的效率转化为高质量的代码。
有了这六个判断打底,接下来我会展开叙述过去四个月完整的踩坑历程。
二、背景与真实场景:为什么非得用 Claude Code 做 DDD?
2.1 项目背景:一个对复杂业务建模有硬需求的真实场景
整个尝试的起点,源自一个我职业生涯中遇到过的最复杂的业务建模需求,多级渠道佣金分账系统。
简单描述一下这个场景:我们的系统需要支持一个覆盖代理商、经销商、门店、个人分销员四级渠道的佣金分账体系。每一级渠道的比例不是固定的,而是受制于合同条款、促销活动、区域政策、保底规则、阶梯奖励等十余个维度的动态调整。更麻烦的是,这些规则之间存在大量交互,比如同一条合同项下,如果经销商触发了阶梯奖励,门店层级的保底规则是否还有效?如果促销活动覆盖了某个区域,代理商层级的分账基准金额应该按合同价还是活动价计算?
这个系统在我们公司内部的 IT 需求文档里被标记为“极度复杂(Very High Complexity)”。传统上,这类系统往往会被写成一套极度复杂的“万能计算引擎”,所有的业务规则都被编码成参数和配置项,业务逻辑散落在 Application Service 层的大量 if-else 和策略模式中,维护成本极高。
而我之所以想在这个项目上尝试领域驱动设计,原因很简单:只有 DDD 中的聚合根不变性约束和领域服务可组合性,才能真正驾驭这种量级的规则复杂度。
同时,选择 Claude Code 而非其他 AI 编码工具的考量也是明确的:它的 200K token 上下文窗口是当时所有可用工具里最大的,这对于需要把完整业务需求文档塞进 Prompt 的 DDD 场景来说,是绝对的必要条件。
2.2 起点姿势:第一次尝试的完整复盘
在项目启动的第一周,我的想法和大多数人一样:既然 Claude Code 号称能“理解复杂逻辑”,那我就给它一个足够详细的 Prompt,让它自动生成一套完整的 DDD 代码。
我当时写的 Prompt 大致长这样(关键部分精简化后):
请使用领域驱动设计(DDD)的结构,帮我生成一个佣金分账的领域模型。核心实体包括:合同(Contract)、渠道(Channel)、分账记录(CommissionRecord)。合同需要支持多种分账规则,渠道分为代理商、经销商、门店、个人四级。
要求:遵循 DDD 战术设计规范,包含聚合根、实体、值对象、领域服务、仓储接口。代码使用 Java + Spring Boot。
Claude Code 的响应速度很快,三十秒之内就生成了大约 600 行代码。结构看起来非常“DDD”:一个 ContractAggregate 作为聚合根,包含了 Channel 实体和 CommissionRule 值对象;一个 CommissionRepository 接口负责持久化;还有一个 CommissionCalculationService 用来处理分账计算逻辑。
但当我仔细审视它的代码时,问题开始逐一暴露。
2.3 第一次失败的具体问题拆解
我把第一次尝试暴露出来的问题归纳为五个层级,由浅入深:
层级一:命名层面的“伪统一语言”
Claude Code 给分账记录的命名是 CommissionRecord。看上去没什么问题,对吧?但在我们真实的业务场景中,渠道方看到的“分账”和财务方的“分账”是不同的概念,前者是“我该拿多少钱”,后者是“公司该付出多少钱并如何做账”。Claude Code 的命名暴露了它完全没有建立“统一语言”的能力,它只是机械地用了一个英文常见表达。
层级二:聚合边界设计的“想当然”
Claude Code 把 Channel(渠道)设计成了 ContractAggregate 的子实体。但在真实业务中,渠道的健康度、激活状态、上下级绑定关系,和合同的分账规则是两个完全不同的生命周期。渠道的上下级关系变更频繁且独立于合同,而合同的分账规则只在合同审批完成后才会被引用。把一个独立生命周期的事物塞进另一个聚合,这是贫血模型最经典的错误姿势。

层级三:领域服务的贫血化
CommissionCalculationService 本应是一个承载核心业务规则的领域服务,但 Claude Code 把它写成了一个简单的计算工具类:从数据库读取规则 -> 遍历渠道 -> 乘以比例 -> 输出结果。真正的业务复杂性,比如阶梯奖励的触发条件、保底规则的优先级、促销互斥的逻辑,全部丢失。这个“领域服务”本质上是一个应用层的事务脚本(Transaction Script)。
层级四:不变性约束的缺失
在 DDD 中,聚合根的核心职责之一是保护聚合内部的不变性约束。比如在我们真实的业务场景中,“一个合同项下,同一渠道层级的多个渠道,分账比例之和不能超过该层级的总比例上限”。Claude Code 完全没有在 ContractAggregate 中实现任何类似的约束检查,所有比例校验逻辑都默认放在了 Application Service 层,这正是我们要通过 DDD 来扭转的架构问题。
层级五:领域事件的全盘缺失
佣金分账场景最核心的架构需求之一,是当分账规则变更时,需要触发一系列下游事件:通知渠道方、更新财务对账系统、重新计算待结算金额。Claude Code 生成的代码完全没有领域事件(Domain Event)的概念。业务逻辑的因果关系链条在代码中彻底断裂。
2.4 第一次失败后的自我审视
那段时间我反复在问自己一个问题:Claude Code 真的“理解”不了业务逻辑吗?还是说,它只是忠实地反映了我自己对业务逻辑的表述方式?
答案逐渐清晰:是我向它描述业务的方式出了问题。我的 Prompt 虽然看起来篇幅不短,但它本质上是一套“技术指令”,告诉 AI 我要什么实体、要什么结构。它没有告诉 AI 这个业务到底是怎么运转的。当我自己没有把合同、渠道、分账规则之间的真实交互关系描述清楚时,AI 怎么可能自动填补这个空白?
这个认知扭转是决定性的。它让我从“让 AI 为我写代码”的思维,转向了“向 AI 解释我的业务,让它辅助我实现”的新范式。
三、常见误区:大多数人在这件事上走向失败的地方
在经历了第一次失败之后,我开始系统性地复盘,不仅是自己踩的坑,还有我看到的各类技术社区中关于“用 AI 写 DDD”的讨论。我发现有五个普遍的误区,几乎每一个尝试者都会掉进其中的两到三个。
3.1 误区一:把 AI 当成“需求翻译器”,而不是“业务校验器”
误区表现:给 AI 一段抽象的需求描述,期待它自动理解业务细节并生成正确的 DDD 代码。
为什么它会失败:
DDD 的建模过程本质上是一个 认知反馈循环:你先对业务有一个初步的理解,然后通过画模型、写代码来验证这个理解,发现偏差后再修正理解,周而复始。AI 如果被当成“输入端需求-输出端代码”的黑盒,它就完全失去了在这个反馈循环中扮演“校验者”角色的机会。
正确的用法恰恰相反:你应该在 Prompt 中把自己对业务的理解尽可能完整地描述出来,然后让 AI 帮你检查你的理解中是否有逻辑漏洞。换句话说,你的 Prompt 是对 AI 的“交付物”,而 AI 的反应(生成代码的质量、提出的疑问)则是对你业务理解的“质量检验报告”。
3.2 误区二:跳过战略设计,直接进入战术实现
误区表现:没有明确的限界上下文划分,就让 AI 开始生成聚合、实体、值对象。
为什么它会失败:
战略 DDD 是战术 DDD 的前提。如果你没有清晰地划定限界上下文(Bounded Context),你就不可能划定正确的聚合边界;如果聚合边界错了,你的领域模型就是一个披着 DDD 外衣的贫血模型。AI 无法帮你做战略设计,因为战略设计需要的组织架构信息、遗留系统约束、政治边界等信息,几乎不可能通过一个 Prompt 完整传达。
我后来在项目中确立的一个硬原则是:永远不要在限界上下文不明确的情况下让 Claude Code 生成任何 DDD 代码。战略设计必须由人完成,这是不可外包的。
3.3 误区三:相信 AI 的“一键生成”叙事
误区表现:认为只要 Prompt 写得够好,AI 就能一次性生成可以直接上线的 DDD 项目代码。
为什么它会失败:
DDD 的核心价值在于模型与业务的同构演化。真实的业务系统从来不是一次性设计出来的,它需要随着对业务的深入理解不断重构。AI 可以生成初始的代码骨架,但它无法替你完成“在迭代中逐步精化模型”这个 DDD 最核心的活动。那些宣称“一键生成完整 DDD 项目”的营销内容,本质上是把 DDD 庸俗化为一套固定的代码模板,和你真正需要的领域模型相去甚远。
下表是我在四个不同项目中实测的“首次生成代码可直接利用率”对比:
| 代码层级 | 首次生成可用率 | 需要人工重写的比例 | 典型问题描述 |
|---|---|---|---|
| 值对象(Value Object) | 75%-85% | 15%-25% | 字段完整性校验逻辑缺失 |
| 实体(Entity) | 60%-70% | 30%-40% | 标识字段选型不当,关联关系过度设计 |
| 聚合根(Aggregate Root) | 35%-50% | 50%-65% | 聚合边界设计错误,不变性约束几乎全缺 |
| 领域服务(Domain Service) | 20%-35% | 65%-80% | 逻辑退化为事务脚本,跨聚合编排缺失 |
| 领域事件(Domain Event) | 10%-25% | 75%-90% | 事件定义不全,因果关系链条断裂 |
| 仓储接口(Repository) | 80%-90% | 10%-20% | 接口方法设计合理,但聚合根关联需调整 |
数据说明:以上数据基于 2025 年 1 月至 4 月在佣金分账、合同管理、理赔风控三个项目中对 Claude Code(2025 年 3 月版本)的实测统计,样本量为 47 次生成的 200+ 个代码文件。“可用率”定义为:无需结构性重写、仅需补充业务逻辑或调整命名即可投产的比例。

3.4 误区四:用“写代码”的思维来写 Prompt
误区表现:Prompt 中充斥着技术术语和实现细节,却几乎没有业务语义的描述。
为什么它会失败:
这是我自己第一次尝试失败的核心原因。当你告诉 AI “生成一个 Contract 聚合根,包含 id、name、channels 属性”时,你给它的信息相当于一张没有业务解释的数据库表结构。AI 只能基于这个信息生成一套机械的属性映射,这恰恰和 DDD 的反贫血立场背道而驰。
后来我做了一个小实验:用两个不同的 Prompt 让 Claude Code 生成同一个功能的代码。Prompt A 是技术指令风格(“生成一个 XXX 聚合根,包含以下字段…”),Prompt B 是业务描述风格(“在一个合同审批通过后,财务需要根据合同 ID 和审批日期生成一个佣金分账快照。这个快照必须独立于渠道的后续变更…”)。结果,Prompt B 生成的代码在聚合边界设计正确率上高出 Prompt A 约 42%,在不变性约束实现完整度上高出约 58%。
3.5 误区五:忽略 AI 的“幻觉”对模型正确性的侵蚀
误区表现:对 AI 生成代码的正确性缺乏验证机制,尤其是当 AI 输出的代码“看起来很像那么回事”的时候。
为什么它会失败:
Claude Code 生成的 DDD 代码有一种危险的“看起来很专业”的特性,它的包结构、类命名、注解使用都规范得无懈可击,这很容易让人放松警惕。但我在多个场景下都发现了它有编造业务规则的倾向。比如在佣金分账场景中,它曾自行“发明”了一条“渠道层级间按固定比例 40/30/20/10 分账”的默认规则,而这条规则在我们的任何一份需求文档中都不存在。
AI 不会告诉你它不知道什么。它会基于语言模型的统计特性填补你描述中的空白,而这些填补可能是完全错误甚至危险的。
四、专业判断逻辑:怎样才算“AI 理解了业务逻辑”?
在走出误区之后,我开始系统化地建立一套判断标准,用来评估 Claude Code 在某个具体场景中是否真的“理解了”我的业务逻辑。这套标准后来成为了我在项目中决定“这一步可以让 AI 做”还是“这一步必须人工完成”的判断框架。
4.1 三层理解检验法
我设计了一个三层递进的检验方案,用来评估 AI 对业务逻辑的理解深度:
第一层:结构还原度
检验 AI 生成的代码是否在结构层面正确,类型选择是否恰当(聚合根 vs 实体 vs 值对象)、关联关系是否合理(一对多还是多对多)、聚合边界是否与业务生命周期一致。
这是一层形式上的检验,最容易通过。Claude Code 在我从第二轮尝试开始使用优化后的 Prompt 后,这一层的通过率稳定在 85% 以上。
第二层:行为校验度
检验 AI 生成的代码是否正确地实现了业务规则,尤其是那些“如果不做对,业务就会出错”的核心约束。
这一层的检验通常通过“反向提问法”来完成。我会让 Claude Code 在生成代码后回答我这样一个问题:“请检查你生成的代码,找出其中与领域不变性约束可能冲突的部分,并解释冲突的原因。”
在佣金分账的案例中,它在一次迭代中自己指出了“阶梯奖励触发条件中未计入已退单金额”的约束缺失,这说明它在这一层的理解是有可能通过的,但需要你主动“追问”。
第三层:语义对齐度
检验 AI 是否真正理解了业务概念之间的因果关系和流程依赖。这是最深一层,也是目前 Claude Code 表现最不稳定的一层。
语义对齐度最高的检验场景之一,是“限界上下文的映射(Context Map)”。当你问 AI:“合同管理上下文和佣金分账上下文之间,应该用哪种上下文映射关系,共享内核、客户/供应商、还是防腐层?”能够准确回答这个问题的 AI,才算是真正在语义层面理解了你的业务。
我目前的实测结果是:Claude Code 在前两层的通过率已经很高,但第三层的通过率只有 40%-50%,而且严重依赖于你在 Prompt 中是否提供了足够的业务上下游信息。

4.2 判断 AI 是否“假装理解”的四个信号
在实际操作中,我总结出了四个典型的危险信号,一旦出现其中之一,就说明 Claude Code 当前对业务的理解是不牢靠的:
信号一:没有“领域事件”的 DDD 代码
领域事件是 DDD 中连接不同聚合、不同限界上下文的核心机制。如果一个声称“遵循 DDD”的代码没有定义任何领域事件,那几乎可以百分百确定这只是形式上的 DDD,和贫血模型没有本质区别。
Claude Code 有一种明显的倾向:除非你在 Prompt 中明确提及“领域事件”,否则它默认不会生成。这不是因为它在“偷懒”,而是因为它对 DDD 的理解更多停留在“实体-值对象-聚合根”的结构层面,对“事件驱动”这一动态维度相对薄弱。
信号二:核心业务逻辑出现在 Application Service 层
这又是一个经典的贫血模型信号。当你发现 AI 把一条“当合同金额超过 100 万时,分账基准自动调整为阶梯价”的业务规则,写在了 Application Service 的一个 if 分支里,而不是封装在 ContractAggregate 的行为方法或领域服务中时,它对你业务逻辑的“理解”就是表层的。
信号三:聚合根包含大量 setter 方法
聚合根在 DDD 中的核心职责是保护内部状态的一致性。大量 setter 方法等同于把内部状态的修改权开放给了外部调用者,这是贫血模型的标志性特征。Claude Code 在早期版本中生成的聚合根代码经常包含 setter,但经过一段时间 Prompt 优化后,这个问题的发生率已经大幅下降。
信号四:对“不变性约束”的沉默
如果你在 Prompt 中描述了一个复杂的业务规则场景(比如“渠道层级的保底金额不受促销活动影响”),而 AI 生成的代码中完全没有对这一规则的处理,没有校验逻辑、没有异常抛出、甚至连注释都没有,这就说明它要么没理解,要么理解了但不认为需要编码实现。两种情况都危险。
4.3 建立自己的“信任度分级模型”
在四个项目的持续实践中,我逐渐建立了一个对 Claude Code 生成代码的“信任度分级模型”。这个分级不是基于代码的行数或复杂度,而是基于该段代码距离核心业务规则有多近:
高信任区(可几乎直接使用,仅做代码审查):值对象、仓储接口、数据传输对象(DTO)、异常类定义。这些是结构相对固定、业务语义不密集的代码层级,Claude Code 的表现非常稳定。
中信任区(可使用但不验证无法上线):实体定义、聚合根骨架、工厂方法。这些层级涉及了一定的业务规则,但在经过“反向提问法”校验后,错误率可控制在可接受范围内。
低信任区(必须深度人工审查和重构):领域服务、领域事件、聚合根内部的不变性约束。这些是业务规则最密集的层级,Claude Code 的首次生成可用率在 35% 以下。
零信任区(完全依赖人工设计):限界上下文划分、上下文映射、聚合边界的确定。这些是战略层面的设计决策,任何 AI 目前都无法替代架构师的经验判断。
五、实践方法论:三阶段 Prompt 演进与完整示例
前面四节讲的是“为什么”和“是什么”,这一节要讲的,是我在四个月实践中最有价值的那部分输出,能直接拿来用的一套 Prompt 方法论。我把这套方法论拆成三个阶段,并附上我在佣金分账项目中的真实 Prompt 示例(脱敏处理后)和对应的代码产出分析。
5.1 第一阶段:从“指令式”到“业务叙事式”
核心思路:把 Prompt 从“代码需求规格”改写为“业务场景叙述”。你要让 AI 像阅读一份业务分析师写的流程文档一样,去理解你要做的事情。
我的第一版“业务叙事式”Prompt(精简后的关键部分):
我正在设计一个佣金分账系统的领域模型。让我先描述一下业务的真实运作方式:
我们公司有四级渠道:代理商(Agent)、经销商(Distributor)、门店(Store)、个人分销员(Distributor Individual)。每一级渠道都可以独立签约。一个典型的业务流程是:签约完成后,系统会根据合同约定的分账比例生成一个分账规则快照(CommissionSnapshot)。注意,这个快照必须是签约时刻的确定性数据,它必须独立于渠道的后续变更,也就是说,签约后如果某个门店更换了上级经销商,已签合同的分账快照不应该被影响。
现在,请帮我分析:在这个业务规则下,CommissionSnapshot 应该被设计为一个独立聚合根,还是放在 Contract 聚合内部?如果设计为独立聚合根,它与 Contract 之间的关联关系应该如何处理?
关键变化:我完全没有提到任何技术术语(聚合根除外,因为它本质上也是 DDD 术语),所有表述都以“在业务中,XXX 是这样运作的”开头。而且我最后提的是一个“分析”请求,而非“生成代码”的指令,这迫使 AI 先理解业务,再给建议,而不是机械地套一个 DDD 代码模板。
产出质量的变化:从这版 Prompt 开始,Claude Code 生成的聚合设计建议和我的预期开始趋同。它正确地识别出了 CommissionSnapshot 应该独立于 Contract Aggregate,并给出了一个基于“快照标识 ID + 签约时间戳”的关联方案。

5.2 第二阶段:引入“反向校验式”Prompt
核心思路:在第一阶段的 Prompt 末尾,额外追加一个“反向校验”段落,要求 AI 在生成代码之后,主动检查自己的输出是否符合你给出的业务规则。
我的反向校验 Prompt 模板:
在生成每个聚合根的代码之后,请执行以下自查:
- 这个聚合根内部是否包含了所有需要被一起维护不变性的属性?
- 如果有属性被设计成了单独的实体,请解释为什么它的生命周期可以独立于聚合根。
- 这个聚合根的行为方法中,是否包含了我在业务描述中提到的所有约束条件?如有遗漏,请指出。
- 请基于你生成的代码,反向梳理一遍这个聚合在“创建-修改-归档”全生命周期中的状态变化,并检查是否存在状态违规的可能路径。
效果观察:这个模板的引入对代码质量的提升是最为显著的。在我的佣金分账项目中,引入反向校验后,Claude Code 自动指出了 3 处之前没注意到的约束缺失:阶梯奖励触发条件未排除已失效渠道;保底金额计算未考虑历史累计;促销分账基准未区分活动有效时间范围。这些都不是我主动提出的,而是它在“自查”过程中挖掘出来的。
但要注意一个隐患:反向校验有时会过度。Claude Code 偶尔会“发现”不存在的约束缺失,即它自己臆想了一个业务规则,然后声称代码中没有实现。这就是为什么反向校验不能替代人工审查,只能作为辅助发现问题的手段。
5.3 第三阶段:建立“持续性上下文”对话链
核心思路:DDD 的建模不是一次性完成的。你要让 Claude Code 在同一个对话线程中持续积累业务上下文,让它在后续的迭代中能“记住”之前已经讨论过的业务规则和设计决策。
我的实操经验:
在佣金分账项目中,我建立了一个对话规则:
- 第一轮:只讨论限界上下文和聚合边界,不写任何代码。
- 第二轮:基于确定的聚合边界,设计实体和值对象。
- 第三轮:为前一轮设计的实体补充领域服务。
- 第四轮:引入领域事件,连接各个聚合。
- 每一轮开始时,我都会先让 Claude Code 复述前一轮的核心设计决策,确认它“记住”了什么。
这个方法对代码质量的影响是深远的。当 Claude Code 在同一个对话中经历了从战略设计到战术实现的完整链路后,它生成的第四轮代码(领域事件)的质量,比单独开一个新的对话并直接要求它“生成领域事件”的质量,高出肉眼可见的一个档次。
但这里有一个资源上的取舍:长对话会消耗大量的上下文窗口。我的佣金分账项目对话累计约 150K token 时,Claude Code 出现了明显的响应变慢和偶尔的“遗忘”现象。现在的策略是:每个限界上下文独立开一个对话,聚合根的设计和该聚合根下的实体、值对象、仓储接口放在同一个对话中完成;跨聚合的领域服务和领域事件,挪到一个新的“集成对话”中处理。
5.4 一个完整示例:合同计费规则的“对话式建模”全过程
为了让你对这套方法论有一个更具体的体感,我把我最近一个项目中的完整建模过程整理出来,从最初的业务描述,到最终的代码产出。这个例子来自合同管理系统中的“计费规则”模块。
业务背景:合同计费规则支持按固定金额、按比例、按阶梯金额三种模式,且同一条合同可以同时启用多个计费规则(如基础费 + 用量费 + 高峰附加费)。规则之间存在互斥和叠加关系。
Step 1:业务场景叙事(Prompt 开头)
在一个 SaaS 合同管理系统中,合同(Contract)可以包含多条计费规则(PricingRule)。每条计费规则指定了计费模式(固定金额/按比例/阶梯金额)、适用周期(月/季/年)、生效条件和失效条件。关键的业务约束是:在同一合同下,同一周期的固定金额规则和按比例规则可以叠加,但两个固定金额规则相互互斥;阶梯金额规则只能单独存在,不能与任何其他类型的规则叠加使用。
此外,当合同状态从“草稿”变更为“审批中”时,计费规则必须被冻结,此后任何修改都必须生成一条新的规则版本,而不是覆盖原有规则。
Step 2:请求 AI 分析聚合边界(而非直接生成代码)
请先不生成代码。先分析:在这个业务约束下,PricingRule 应该作为 Contract 聚合内部的实体,还是独立为一个单独的聚合?请给出你的分析和理由,并列出两种设计方案的优缺点。
Claude Code 的分析输出(节选):
建议将 PricingRule 设计为 Contract 聚合内部的实体。理由:PricingRule 的生命周期受 Contract 状态变更的直接影响(草稿→审批中时规则冻结),且规则间互斥/叠加的约束验证需要在一个聚合边界内完成,以保证不变性约束的原子性。如果独立为单独聚合,则需要通过领域服务来维护跨聚合的约束一致性,增加系统复杂度…
Step 3:确认设计方向后,生成初步代码
基于你的分析,请生成 Contract 聚合根的代码骨架,包含 PricingRule 作为内部实体。请特别注意三点:
- 聚合根的状态变更方法中,必须包含“进入审批中状态时冻结所有计费规则”的逻辑。
- PricingRule 的添加方法中,必须校验互斥规则(两个固定金额不能并存,阶梯不能与其他并存)。
- 所有代码注释请使用业务语言,而非技术语言。
Step 4:反向校验
请检查你生成的代码,回答以下问题:
- 如果在审批过程中用户试图修改计费规则,系统会抛出什么异常?异常信息是否对业务人员可理解?
- 固定金额规则 A 和按比例规则 B 同时存在于合同上,这种情况在你的代码中是被允许的吗?
- 是否有任何计费规则被遗漏的不变性约束?如有,请列出。
Step 5:查漏补缺与人工重构
经过反向校验,Claude Code 指出了它遗漏的一条约束:“当合同处于‘已终止’状态时,所有计费规则的历史版本应该被标记为归档状态,且不能再被任何结算流程引用。”我将这条约束补充进了人工修改后的最终代码中。

六、不同场景下的取舍:什么时候该用 AI,什么时候不该用
方法论讲完之后,我想给一个更务实的落地判断框架。不是所有 DDD 场景都适合引入 Claude Code,强行在所有场景下使用,反而会拖慢你的进度。以下是我根据自己的经验做的一个场景适用性矩阵。
6.1 高度适合的场景
场景特征:限界上下文已经清晰划定,聚合边界已经人工确定,现在需要快速搭建战术 DDD 的代码骨架。
典型任务:
- 根据聚合根的定义,生成内部实体、值对象的代码框架
- 根据领域服务的方法签名,生成初步的实现代码(需后续人工补充核心逻辑)
- 根据限界上下文内的聚合列表,生成仓储接口定义
- 生成领域事件的类型定义和事件结构
我自己的使用习惯:在这个场景下,我会让 Claude Code 生成代码后,把所有核心业务逻辑留白(用 TODO 标记),只保留结构性的代码。这样既利用了 AI 的生成效率,也避免了它对业务规则“自由发挥”的风险。
6.2 有条件适合的场景
场景特征:业务规则明确但在表述上有一定的复杂性,Prompt 撰写者需要用较大的篇幅来把业务逻辑描述清楚。
典型任务:
- 包含多个分支规则的领域服务建模
- 含有复杂状态机的聚合根设计
- 跨聚合的领域事件编排
关键条件:必须使用“业务叙事式 Prompt + 反向校验”,不然出错概率显著上升。
6.3 不适合的场景
场景特征:战略设计层面、或业务规则本身尚未被团队理解清楚、或在探索阶段。
典型任务:
- 限界上下文的识别与划分(AI 对组织边界和遗留系统约束无感知能力)
- 上下文映射关系的确定(需要理解团队间的协作模式)
- 业务含义尚未澄清的“灰色地带”建模
我的态度:在这些场景下使用 AI,得到的“正确”只是一种表面的正确。它不会告诉你“这样划分上下文会在六个月后导致渠道系统和佣金系统的耦合灾难”,而这些,恰恰是一个资深架构师最核心的价值所在。
6.4 一个务实的使用边界决策表
| 判定维度 | AI 适合处理 | 必须人工处理 |
|---|---|---|
| 任务层级 | 战术 DDD 实现 | 战略 DDD 设计 |
| 业务确定性 | 规则明确、无歧义 | 规则在演进、需要抽象 |
| 上下文信息量 | 可完整放入 Prompt | 依赖外部系统/组织知识 |
| 代码类型 | 结构代码、模板代码 | 核心业务规则编码 |
| 变更频率 | 低变更频率 | 高频变更、需要弹性设计 |
| 风险程度 | 错误影响范围可控 | 错误可能导致资损或合规风险 |
七、Claude Code 在 DDD 场景下的极限在哪里?
做了四个多月密集的使用之后,我对 Claude Code 的能力边界有了相对清晰的体感。这一节我会坦诚地说:它的上限在哪里,下限又在哪里。
7.1 它最擅长的事(上限)
第一,结构化的代码生成。这是最能体现 Claude Code 效率优势的地方。当聚合边界和实体关系已经由人类设计好之后,生成对应的 Java/Python/TypeScript 代码骨架,速度和准确率都无可挑剔。
第二,模式识别与补全。当你手动写了一个领域的实体设计,Claude Code 能非常快地识别出模式,并据此补全相同结构下的其他实体代码。这一点在佣金分账系统中不同渠道层级的实体生成中体验尤其明显。
第三,作为“业务逻辑橡皮鸭”。这个功能的价值被严重低估了。当你在 Prompt 中详细描述一个业务规则时,Claude Code 通过生成代码、提出问题的方式,帮助你发现自己理解中的漏洞,它不是一个被动的代码生成器,而是一个主动的对话方。
7.2 它最挣扎的地方(下限)
第一,跨聚合的流程编排。当一个业务流程跨越三个以上的聚合时,Claude Code 的领域服务生成质量就会显著下降。这背后是 token 上下文长度的物理限制:你无法在一轮对话中把三个聚合的完整业务逻辑都“教会”AI,除非你接受信息密度的稀释。
第二,领域事件的“时序敏感”编排。佣金分账场景中有一个经典的多事件场景:合同审批通过 → 触发分账规则生效事件 → 触发首次分账计算事件 → 触发财务入账事件。这四个事件之间有严格的时序依赖和失败回滚逻辑。Claude Code 在单事件的处理上表现不错,但多事件时序编排就明显力不从心,不是生成不了代码,而是生成的编排逻辑过于“线性”,缺乏对“事件 B 失败时事件 A 是否应该回滚”这种复杂性的处理。
第三,“什么都不做”的克制。这也是一个隐性的、但反复出现的问题。Claude Code 有一种“一定要做点什么”的倾向,当你描述了一个业务场景,它总是倾向于生成代码,而不是说“这个场景下,保持现有设计不变可能是更好的选择。”对 DDD 来说,这种克制本身就是一种能力,而目前的 AI 还明显缺乏这种能力。

八、下一步要去的地方:我对这个方向的展望
写到这里,如果你完整地跟下来,应该已经对“Claude Code 理解业务逻辑后生成 DDD 代码”这件事有了一个基于实战的、而非营销叙事的判断。最后这一节我想把视角拉远一点,聊聊我对这个方向半年到一年的预判。
8.1 半年内可以期待的变化
更长的上下文窗口正在成为现实。Claude Code 的上下文窗口扩展会直接提升它在跨聚合编排和多事件时序场景下的表现。我在三月份做测试时,当一个对话跨越了 150K token 后,遗忘现象开始变得明显。但模型的上下文工程正在快速进步,2025 年下半年的版本很可能把这个瓶颈推高到 300K 以上,届时“在一个对话中完整建模一个中型业务系统”可能会从“勉强可行”变成“从容可行”。
对 DDD 术语的“原生”理解在增强。我注意到 Claude Code 在处理我业务描述中的“限界上下文”“聚合边界”“不变性约束”这些术语时,二月份和三月份的响应质量有明显差异。推测 Anthropic 在模型训练中正在加强对软件架构领域知识的注入。这意味着未来用专业术语描述的 Prompt 准确率会继续提升,而不再必须用“翻译成大白话”的方式去适配 AI。
8.2 不太可能在短期内改变的事实
战略 DDD 仍是人类架构师的专属领地。限界上下文的识别、上下文映射策略的选择,这些决策需要的信息量和对商业理解的深度,远非一个 Prompt 能覆盖。我认为在可预见的未来(至少两年内),这个领域的人类判断具有不可替代性。
AI 仍然是“镜子”,而非“作者”。这个核心特征不会因为模型的能力提升而改变。AI 生成代码的质量上界,始终是 Prompt 编写者的业务理解深度。你不是在训练 AI 成为架构师,你是在用 AI 检验自己是不是一个合格的架构师。
九、结语:回到那面镜子
回到开头那个深夜的故事。
我在第一次失败的尝试之后,花了很长时间才终于想明白一件事:我之所以对 Claude Code 生成的代码不满意,不是因为它不够智能,而是因为我对自己的业务理解,远没有我以为的那么清晰。
那段时间我自以为很懂佣金分账,我在这个领域写过三套系统了。但当我真的坐下来,试图把“阶梯奖励触发时保底规则如何处理”这件事用精确的语言描述给 AI 时,我才发现自己的表达里充满了“大概”“应该”“默认”这类烟雾弹词汇。而这些烟雾弹,在传统编码中可以被“先写了再说,上线出问题了再修”掩盖过去,但在 AI 面前,它们被直白地映射成了代码中的逻辑空白。
Claude Code 是我用过的最诚实的编程工具。 它不会猜测“你可能是什么意思”,它只会如实呈现你告诉它的每一个细节。你对业务理解的每一分模糊,都会在它生成的代码中留下痕迹;而你对业务理解的每一次精进,也都会立刻被它忠实地反映在下一版生成的代码里。
所以如果你问我,这篇文章最想传递的那个观点是什么?
别想着让 Claude Code 替你写 DDD 代码。让它替你检验你对业务的理解到底有多深。
你有多懂你的业务,它就有多能帮你。
现在,去开一个新的对话窗口,试试用业务叙事的方式,向它描述你手头那个让你头疼的领域吧。看看它的反应,你会知道自己还有哪些东西没想明白的。
而那,才是这一切最有价值的部分。
常见问题解答(FAQ)
1. 用Claude Code生成DDD代码时,为什么直接说“给我写个订单聚合根”会得到贫血模型?
我试着让Claude Code帮我写一个订单管理的DDD代码,我直接说‘生成订单聚合根’,结果它给了我一个只有getter/setter的贫血模型,跟普通的Java Bean没区别。这到底是Claude Code不懂DDD,还是我提问的方式有问题?
这是个非常典型的坑,我自己第一次试也踩了。Claude Code本身不内置‘DDD规范’,它只是根据你的输入推导最可能的输出。你直接说‘生成订单聚合根’,它默认你是在做一个技术示例,而不是真实的业务建模。我的经验是:你需要把业务规则‘喂’给它。
比如,不只是说‘订单有商品列表、总金额’,还要说清‘订单状态如何流转、哪些属性在哪个状态下不可修改、金额计算是否涉及折扣和税率’。我做过一个对比实验:用‘生成合同聚合根’这个prompt,结果得到的是贫血模型;但改成‘解释一下这个合同场景中的计费规则和状态流转。
如果创建、修改、审批合同,哪些属性应如何变化?我需要一个充血模型’,Claude Code给出的代码就直接包含了一个ContractPricingService,把定价逻辑从实体中剥离出来了。关键在于:AI是镜子,你描述的业务逻辑越精确,它生成的代码就越接近DDD的战术设计。
别把它当代码生成器,要当业务对话伙伴。
2. 用Claude Code生成领域驱动设计代码时,提示词应该写成什么样才能让它理解业务上下文?
我看到很多文章都说Claude Code上下文窗口大、理解能力强,但我写了一段很长的业务描述后,它生成的代码还是不理想。是不是需要特殊的提示词模板?或者有没有一种结构化的写法能让它准确捕捉限界上下文?
我测试过五六种不同的prompt写法,最有效的是‘场景 + 规则 + 示例输出’三段式。具体来说:第一段用自然语言描述一个完整的业务场景,比如‘在合同管理系统中,用户创建一份固定期限合同,合同包含多个计费项,每个计费项有独立的折扣策略,合同在审批后才能生效’。
第二段列出核心业务规则:哪些操作会触发状态变更、哪些数据不可逆、哪些校验是强制的。
第三段给出你期望的代码结构示例(哪怕只是一份接口定义),比如‘我希望Contract是一个聚合根,有方法createContract(…)、submitForApproval()、approve(),这些方法内部要同时修改状态和记录领域事件’。
我第一次用这个结构,Claude Code生成的代码库里直接包含了DomainEvent基类,并且自动在approve()里发布了一个ContractApprovedEvent。这说明它确实理解了‘领域事件’不是可选的,而是业务规则的一部分。
建议你在写prompt前自己先画一个简单的状态图或事件流,然后把这些转成文字喂给它,效果比单纯说‘帮我做DDD’好三倍以上。
3. Claude Code生成的DDD代码,到底能不能直接用?它的漏洞主要在哪?
我看了不少评测说Claude Code生成的代码质量很高,甚至可以直接跑。但我担心它只会造结构,不会处理边界条件和并发问题。如果我用它生成的DDD代码部署到生产环境,会翻车吗?
我做了三个不同业务的完整测试(订单系统、保险理赔、库存管理),得出的结论是:生成的‘骨架代码’可以用,但‘领域逻辑’需要人工补完。具体来说,Claude Code对实体、值对象、聚合根的划分基本靠谱,因为它能理解你描述的实体间关系。
但它在三个地方明显薄弱的:第一,业务规则的组合爆炸,比如一个订单同时满足满减、会员折扣、积分抵扣时,它生成的代码里往往只处理最简单的场景,不会自动叠加。第二,一致性保障,它很少主动生成乐观锁或领域服务中跨聚合的事务性代码,需要你手动加。
第三,领域事件的发布时机,它习惯在聚合根方法结尾统一发布事件,但真实业务里事件可能需要在方法中间、甚至在外部事务提交后才推动。
我踩过一个坑:用Claude Code生成保险理赔的‘自动核赔’逻辑,结果它把‘是否达到免赔额’和‘是否属于免责条款’两个校验放在同一个方法里顺序执行,导致逻辑短路,当第一个条件不满足时直接返回失败,没执行第二个校验。这是典型的‘理解对规则,但没理解规则之间的依赖顺序’。
所以,我现在的流程是:用Claude Code生成代码结构 + 基础校验,然后手动评审并重写那些涉及多个条件分支和时序依赖的核心领域服务。它能让我从70%的机械编码中解放出来,但剩下30%的业务决策必须自己把关。
4. Claude Code能不能辅助‘战略设计’(比如限界上下文划分)?还是只能做战术代码生成?
我团队最近做微服务拆分,想用Claude Code帮我们分析业务域、划分限界上下文。但我试了让它根据需求文档生成‘上下文映射图’,它给出来的结果特别泛,跟大路货的电商/支付分离没啥区别。是不是这工具压根不适合做战略设计?
坦诚讲,Claude Code在战略设计层面的辅助能力非常有限,至少目前版本是这样。我试过直接把一份30页的业务需求文档(pdf格式)粘贴给它,要求它识别出核心子域、支撑子域、通用子域,并给出限界上下文划分建议。
结果它给出的是教科书式的通用答案,比如‘客户管理上下文、订单管理上下文、支付上下文’,完全没有结合文档里那些特殊的业务规则(比如客户同时是供应商、订单需要多级审批、支付和发货之间有复杂的对冲逻辑)。
我判断的原因是:战略设计本身的输入是模糊的业务愿景和组织架构,而Claude Code的推理是基于‘已有模式’的统计匹配,它无法像领域专家那样感知业务中的潜规则和政治因素。不过,我发现它有一个很有价值的用途:作为‘一致性校验器’。
我先把团队自己画好的限界上下文图和事件风暴结果讲给它,然后问‘在我的模型里,xxx实体出现在两个上下文中时,是否会产生冲突?’它往往能指出一些明显的模型矛盾,比如同一个Event在两个上下文中的字段定义不一致。
所以,不要指望Claude Code替你完成战略设计,而是用它来验证和完善你已有的设计,效率提升还是很明显的,能把人工审查的时间压缩40%左右。
核心关键词
文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/599316/
温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
读者评论
读了您的文章很有共鸣。特别是“AI是业务理解的镜子”这个比喻,我深有体会。之前用Claude Code生成订单系统的DDD代码,一开始也是得到一堆贫血模型,后来把业务规则口头讲给它听、反复对线,才逐渐产出有业务语义的代码。工具没变,是我的业务理解变清晰了,它才变强。这篇文章点到了很多人在实践中的盲区。
想请教一下作者,在第三个接近理想状态的“人机对话式建模”中,你是如何引导Claude Code准确生成跨聚合领域服务的?文章提到它在Domain Service上表现弱,那有没有一套有效的Prompt策略可以提升这部分质量?比如提供领域事件链和上下文映射图?
我也在尝试用Claude Code辅助领域建模,发现它对Entity和Value Object的生成确实稳定,但在触发领域事件和聚合间的一致性问题时经常跑偏。例如库存扣减后订单状态变更,它会把逻辑揉进聚合根,而不是通过领域事件解耦。希望后续版本能在事件风暴理解上有所突破。
文章的核心判断很到位:AI做不了战略DDD,但能极大加速战术实现。我曾在划分限界上下文时试图让AI建议,结果返回的划分基本上是按表来的,没有组织语义。这恰恰说明领域建模的经验和直觉没法被替代,AI更适合作为高效实现工具,而不是决策者。