DDD领域驱动设计批评文集
做强化自测题获得“软件方法建模师”称号
《软件方法》各章合集
张逸老师最近写了一篇《SDD工程化落地:双环驱动开发流程》(https://mp.weixin.qq.com/s/AXgQR5wxKvQXu8zpZIWUfw)。
搜索“双环驱动”,这个词在软件业未出现过,应该是DDD圈子为业界贡献的又一个新词。

当然,如果去搜OpenSpec+Superpowers的结合,类似的内容还是不少的,例如https://github.com/danielhanold/superspec,只是没有造一个类似于“双环驱动”的词。
本文不讨论张逸老师的整篇“双环驱动”是不是有价值、是不是创新等等,因为很多东西我也只是了解点皮毛。
我只说相对于其他人来说,我特别懂的那部分内容。
**********
张逸老师在“双环驱动”文章中写了一份用例规约,本文就来评点一下这份用例规约。
2021年,我曾经写了一个系列三篇文章,评点张逸老师的“业务服务”,本文的内容类似该系列中的第三篇:
《“创新”何太急-评张逸的“业务服务”(三)系统用例是“深入到系统内部”?》(https://mp.weixin.qq.com/s/OFhJGDdLpkd-HwCeVixCQw),以下称《评业务服务 三》。
所以,读者阅读本文的评点后,不妨翻一翻5年前的文章《评业务服务 三》,搜索关键词对比看看,类似该评点指出的问题,《评业务服务 三》是否已经指出过?
**********
张逸老师原文如下:

我在图上标了13个要评点的地方,计划和2021年一样,写三篇文章来评点。
原文[01]
基于软件工程的实践
随着AI横扫编码工作,谈论“软件工程”的人多了起来。一些之前对软件工程一无所知,甚至在一无所知的情况下随意诋毁软件工程的人,摇身一变,大谈AI时代的软件工程,不由让人产生错觉,似乎他们历来是支持软件工程的。
典型的例子,我在《软件方法》第1章提到的,曾经说过“我一直排斥软件工程”、“关于软件工程,我并不看重”的北京大学计算机科学博士,这些天也在谈AI时代的软件工程。
大家可以观察一下有没有这样的现象,包括国内国外。
可能有同学说,这不是好事吗?未必!如果涌进来一帮人只喊口号,干的事情却背道而驰,最后的结果是把这个词搞臭了。“敏捷”、“领域驱动”就是前车之鉴。
社会层面上,“福报”、“名媛”、“圣母”、“理中客”、“情商高”这些褒义词现在在人们心中是什么印象?
之前我写过《DDD圈子开始岁月史书了》和《搞岁月史书时,能否不要打腾讯的旗号》已经触及过这个“突然大谈软件工程”的问题,接下来我还会专门写文章。
以上只是有感而发,和张逸老师的“双环驱动”文章无特定关系。
原文[02]
个人建议使用UML中的用例规约,会是最佳选择。
和2021年相比,张逸老师在这里不使用“业务服务”了,也不再鼓吹“用户故事”,而是推荐了“用例规约”,这是值得鼓励的,比DDD圈子的新生代不知道高到哪里去了——那真是叫人瞠目结舌。
虽然推广用例超过二十五年,“用例是最佳选择”这样的说法我都没有说过。张逸老师确实是敢说。
不过,在这里倒是可以顺便给出后文需要反复用到的知识点:
知识点一
系统用例规约:系统需求的组织形式之一。
知识点二
系统需求:在涉众利益的平衡之下,系统【作为整体】【必须】满足的功能、性能和设计约束。
如果理解了知识点二,不管用什么方式写需求,本文所评点的绝大多数错误都不会犯了。
原文[03]
创建生成订单
此处应该是打字错误,把“生产”写成了“生成”。
其他没有什么要评点的地方,此处列出来只是表示我认真阅读了,看见了这个小错误。
原文[04]
参与者:计划员
前置条件:用户已登录且具有“创建生产订单”权限。
(1)用词要统一
张逸老师在这里使用了“参与者”(说的应该是Actor)、“计划员”和“用户”
既然写的是用例规约,那就不要写“用户”了。
比起Actor,“用户”这个词有哪些问题,可以在以下地方搜索关键词“用户”:
*《评业务服务 三》(https://mp.weixin.qq.com/s/OFhJGDdLpkd-HwCeVixCQw)
*《CTO也糊涂的常用术语》(umlchina.com/url/cto.html)
*《软件方法》第5章(抱歉,无法给出下载链接)
*《软件方法》自测题(umlchina.com/url/quiz.html)
如果极度喜欢“用户”(那咋啦!),坚决抵制Actor,也可以勉强用“用户”,不用“参与者”,但不能既用这个,又用那个。
下面这几个,至少用词是统一的:
参与者:计划员
……参与者已登录
参与者:计划员
……计划员已登录
用户:计划员
……用户已登录
用户:计划员
……计划员已登录
但不能写:
参与者:计划员
……用户已登录
这里也可以看到我前面提到的“喊口号”现象。
DDD圈子动则念经“统一语言”,似乎没这几个字之前软件开发人员都是傻子,但在行动中却非常随意,一点都不“统一”。
当然,如果像《可不是咋的!产量高的领域驱动设计作品评点01》(https://mp.weixin.qq.com/s/P_x91We8GUPJwWrsJcu1sg)所评点的作品那样,通过换词带来新鲜感,从而达到“投资少、见效快、产量高、门槛低、仪式感十足”的效果,那请随意。
★Actor我使用的翻译是“执行者”,但这不是本文的要点。为减少译名的争议,后面我在自己的文字中只使用Actor,不使用“参与者”或“执行者”。
还有另外的问题:
(2)“已登录”不是前置条件
(3)用例的Actor不是为了权限管理
(2)(3)这两个问题,要展开讲,篇幅较大。《软件方法》第5章有专门的内容,感兴趣的读者可以阅读并做题自测。
原文[05]
后置条件:新生产订单记录生成,状态为“已创建”。
(1)用例规约里不需要“状态”
可能需要阅读一些预备知识——如果不理解我接下来的评点,可以回到这里来看:
*[全文]DDD话语批评之一:评张逸的“状态和事件本质相同”
https://mp.weixin.qq.com/s/QhAhSdET5psZQEEW6f9KoA
*[答疑]关于《评“状态和事件本质相同”》的6个疑问
https://mp.weixin.qq.com/s/e8XSGrS2bfnnliW34zZnbA
*美女放电还是整形-从《人月神话》误译谈状态机图
https://mp.weixin.qq.com/s/8khYe1m1DVXf28U-9it7-w
*[答疑]啪啪、贤者模式和状态机
https://mp.weixin.qq.com/s/xX3zYpS_mVYFwXucAE0NBg
*[pdf、epub]370道《软件方法》强化自测题业务建模需求分析共310页(202606更新),做自测题里面和状态机相关的题目
https://mp.weixin.qq.com/s/pjlACk-RGWnhgr2gfJzRtw
好,开始评点。
为了更好地讲解知识,我换一个领域知识更广为人知的“婚姻登记管理信息系统”。
民政局婚姻登记处的工作人员用系统办理婚姻登记,用例图:

(不知目前的婚姻登记信息管理系统,在这个用例中是否需要和两位当事人交互,就假设不需要吧。)
那么,“办理婚姻登记”的用例规约里是否可以写:系统修改当事人的状态为“已婚”?
先说答案:对用例规约来说不合适。
不过,要讲清楚为什么,没那么简单。
不同的范式
用例规约目前表示形式大多是文本,主体类似这样:
主Actor做某事
系统做某事
系统请求辅Actor做某事
本质上可以看作以目标系统以及Actor为泳道的活动图。

活动图上,结点用动词命名,表示行为,把输入转化成输出;边上面流动的是用名词命名的项(Item)。对信息系统来说,Item就是信息,如果扩展到更广泛的系统,Item还可以是物质和能量。
边上还流动着代表着控制权的令牌,但令牌流不会在图上显式出现。简单的活动图中,Item的流动也隐去。
状态机图则是这样的:

状态机图描述某个类的行为规则。类用名词命名。
★如果看到这里有类似这样的疑问“申请也可以是一个类,那不是动词吗”,可以看《软件方法》8.2.4.5 命名的词性(umlchina.com/url/softmeth.html搜“pdf”)。
状态机图上,结点用形容词命名,表示状态;边表示迁移,主要成分用动词命名。
如果一定要用状态机来表示系统的需求,也是可以的。我们把系统当作一个整体,建模它的状态机,Actor的“做某事”相当于迁移的斜杠左侧的动词,系统的“做某事”相当于迁移的斜杠右侧的动词。
这时,得到的确实是需求,但就别叫用例规约了,因为它不是描述某个用例的。
你怎么知道有这个状态?
抛开上面所说的范式区别不谈,我们就来看这个问题:
你怎么知道“当事人”的状态机是系统应该关注的,你怎么知道“已婚”是“当事人”的一个有意义的状态?
换成张逸老师的例子,就是:
你怎么知道“生产订单记录”的状态机是系统应该关注的,你怎么知道“已创建”是“生产订单记录”的一个有意义的状态?
如果读者的反应是:啊?这不是理所当然的吗,傻子都知道啊!
那么,计算机(现在流行的称呼是AI)就可以平推这个知识,压根就不需要人脑来操心——毕竟“傻子都知道”,人脑的贡献为零。
如果说,这里面可复杂了,要日复一日灵修,修炼出DDD的终极大招by experience:

本文可以不用看,灵修可能是更好的选择。
知识点还是在这里面:
*[全文]DDD话语批评之一:评张逸的“状态和事件本质相同”
*[答疑]关于《评“状态和事件本质相同”》的6个疑问
状态是强加的冗余特征,用于表征类的所有属性(含关联)域所构成的笛卡尔积上的一个等价集;对象的属性值落在该等价集内时,遵守的行为规则相同。
我们可以问:如果系统不记住当事人“已婚”这个状态,可能会有什么损害涉众利益的后果?
哦,会导致工作人员给已经有配偶的当事人办理婚姻登记导致重婚。
真正的需求是这样一条业务规则:
不允许有配偶的当事人办理婚姻登记
这条业务规则可能会绑定到这样一个步骤:
系统验证当事人符合办理婚姻登记的条件
这个步骤可能会出现在工作人员使用系统办理婚姻登记时,当然,为了减轻工作人员的工作量,还可以出现在当事人使用系统来预约办理婚姻登记时。
所以,“不这样不行”的需求是:
系统验证当事人符合办理婚姻登记的条件
条件:
*当事人不允许有配偶
但这只是条件之一,根据现行《民法典》,系统应验证而且能验证的其他条件还有:
*当事人性别必须为一男一女
*当事人已达法定婚龄
《民法典》还有一些条件,目前应该无法由信息系统验证,不能成为系统的需求。
*自愿
*当事人之间非直系血亲或三代以内旁系血亲
*若有重大疾病已告知对方(★靠自觉了,惊不惊喜意不意外!)
**********
如果写:
系统修改当事人的状态为“已婚”
相当于往前多迈了几步:
*系统里有一个类叫“当事人”。
——没有进入分析工作流,是不是使用面向对象的分析,使用面向对象的分析是否需要这个类,未可知。
*“当事人”有一个状态叫“已婚”。
——“已婚”这个冗余特征是从类似“配偶s.count>0”的表达式推算出来的,是否适用区分不同行为规则,未可知。
(目前来看应该合适,“已婚”状态下的对象,收到“结婚”的消息,响应是拒绝,这和“未婚”状态下的响应有区别。不过,如果稍微调整一下规则,允许一个人同一时间有多于一个配偶,就会出现“已婚”的人,既可以结婚,也可以离婚,也可以丧偶。)
*系统要预先设置当事人的状态,将来验证时,只需要验证状态,不再做计算。
——这都不属于“不这样不行”。
**********
但是,很多人就喜欢写“系统修改***的状态为***”,因为这样写有好处:一一对应,假装问题解决了。
这一点,参见:
[全文]DDD话语批评之一:评张逸的“状态和事件本质相同”
在文中搜关键词“一一对应”。
(2)不用加“记录”二字
“订单记录”的“记录”是冗余的。
在某个领域概念后面随手加"信息"、"记录"、"数据"、"表"、"库"、"单"等,是常见的批量刷废话。
知识点参见:
《软件方法》8.2.4.5 命名的词性(umlchina.com/url/softmeth.html搜“pdf”)。
不但“订单记录”的“记录”是冗余的,“订单”的“单”也已经有“记录”的意思,我们看《水浒传》:

“订单”实际上描述的是一次"购买"或“交易”,不过"订单"已经在领域中广泛使用,而且把“单”去掉留下“订”从现在的汉语习惯来说也不合适,所以“订单”即使看起来犯了以上提到的冗余错误,也还是可以使用。
但再往上加就不合适了。
当然,如果就是刻意要达到DDD“投资少、见效快、产量高、门槛低、仪式感十足”的效果,可以继续往上刷:
订单→订单信息→订单信息数据→订单信息数据记录→DDD领域实体订单信息数据记录
★什么时候可以加“信息”?当不能用一个概念表达的时候,后文会讲到。
原文[06]
计划员进入“生产订单管理”界面
(1)这是常见的未受过基本训练的错误
==待续==
预先说一下可能出现的某些读者反馈,这些反馈我在书里和文章里老早就说过,并反复提起。
有的读者看了本文之后,可能会:
*拿一本什么书来给我看。你看,上面就是这样做的,我是照着它抄的。
*一定要按照你的UML大法吗,我有自己的规范不行吗?
如果是这样,还是耐心看看我写的道理以及所给的资料吧,就算带着批判和找茬的目的去看也好的。


![[鉴赏]摇身一变鼓吹软件工程-01-Allen Holub-171主机测评](https://www.171host.com/wp-content/uploads/2026/10/20261028051713-6ae18559a4e4b-220x150.png)
