重读领域驱动设计——如何说好一门通用语言

结论先行

在 DDD 中,通用语言是以限界上下文为边界的。如果一个产品或者项目有多个限界上下文,我们就需要为每个限界上下文定义通用语言。

限界上下文提供了一个语义边界,来保持通用语言和领域概念的一一对应关系。

这个约束解决了现实世界中同样的名词在不同场景、时机下对应不同的业务概念所带来的歧义问题,帮助团队在使用通用语言交流的时候可以无歧义沟通。

初尝“通用语言”

最初我对于如何构建通用语言的认识,来自于《领域驱动设计》第一章中的案例。这个案例生动的展示了开发人员如何在和领域专家的沟通过程中,建立了双方理解一致的通用语言,并且使用这个语言来进行双方的沟通。基于那个案例,我当时对构建通用语言的理解就是要:

  • 技术人员使用业务人员的用语作为开发词汇;
  • 划分好聚合,将这些词汇关联到聚合上;
  • 技术人员要将这些词汇映射到代码实现中;
  • 这些词汇会随着项目的发展一点点扩展;

带着这份理解,我在曾经负责过的小型项目上做了一些实践,效果都很不错。在很长一段时间,团队的开发人员体会到了在和业务人员交流时候心有灵犀、会心一笑的快感;也很少听到“这个东西不是我要的”这类批评了。

“通用语言”遇到同名词汇时就变得不清不楚了

然而,当我来到ThoughtWorks参与到一些几十号人的项目时,我发现根据这个原则构建起来的通用语言,在遇到同名多义的词汇时,就无法保证团队内部的沟通是无歧义的。而这种歧义又会导致团队成员说着同样的话想着不同的事情的情况出现,例如:

  • 同名的业务词汇与实际业务关系不清:“为什么不能给销售订单增加一个是否投诉的字段,界面上都是显示在销售订单上的”——销售订单到底是个什么东西,能干什么不能干什么是怎么确定的?
  • 同名的业务词汇与不同的业务词汇关联:“我在销售订单付款后改变了买家信息,为什么我看销售订单的预定里的买家也发生了改变”——这里说的买家信息有几个?
  • 同名的业务词汇之间的关系不清楚:“为什么我变更了profile 上的买家地址,销售订单上的买家地址就跟着改变了” ——这里说订单上的买家地址和profile 上的买家地址是一个什么关系?

通过添加约束消除歧义

下图是 DDD 概念的一个元模型图。从图的左下角,我们可以看到在构建通用语言时,还有两个额外的约束条件:子域和限界上下文。

在 DDD 中,软件的核心是其为客户解决领域相关的问题的能力

这里的领域,就是指软件系统要解决的实际问题相关的东西的集合。

例如:为一个电子商务公司开发一个电商系统,我们就需要围绕这个盈利模式的运营方式、业务规则,比如如何进货,如何促销,如何物流等等了解这个电子商务公司的盈利模式,所有和业务相关的东西都属于领域。

领域分为问题域和解决方案域两部分。

为了分解问题域的复杂度,问题域又会被拆解为多个子域,每个子域都要明确待解决的业务问题和业务流程,以及通过解决业务问题为企业带来了什么样的业务价值(这个是因,业务流程和要解决的业务问题是果)。

在清晰的定义子域后,我们就可以建立通用语言来提取该子域的领域知识,并基于通用语言为解决问题建立领域模型。

一个领域模型会存在于一个限界上下文中。限界上下文在 DDD 中用来定义模型的适用范围、模型的用途、以及在何处保持一致,限界上下文会让团队明确模型的职责边界是什么。同时,通用语言被限定在限界上下文中;限界上下文提供了一个语义边界,在每个限界上下文内通用语言的每个词汇必须和领域概念一一对应。

理想条件下,子域和限界上下文是一一对应。但是子域划分的粒度,遗留系统的现状,语言的歧义,团队结构等子域和限界上下文对应可能是1:N 或者 N:N 的。

通过限界上下文间的映射,上下文中的多个模型会协作以满足系统需求。我们也可以了解在不同上下文中的同名词汇是否存在关系,存在什么样的关系。

对通用语言而言,子域解释了通用语言和现实世界业务活动的关系;限界上下文提供了一个语义边界,来保持通用语言和领域概念的一一对应关系;上下文映射则提供了不同限界上下中的通用语言的转换关系。

来解决下前文的问题

前文所述的订单及订单的相关概念存在着歧义,我们来看下通过子域、限界上下文和上下文映射是怎么消除这些歧义的:

因为同名的业务词汇与实际业务关系不清导致的疑惑

“为什么不能在销售订单中增加一个是否投诉的字段,界面上都是显示在销售订单上的”

假设,这里所说的销售订单存在于销售子域下,那么这个订单应该解决的是销售过程中的问题。订单的生命周期以销售开始到销售终止。一般而言投诉属于售后环节,在销售订单上声明是否投诉字段,意味着销售订单的职能突破了销售子域。UI 上的销售订单展示了聚合的信息,和同名的领域模型不一定保持一致。

因为同名的业务词汇与不同的业务词汇关联导致的疑惑

“我在订单付款后改变了买家信息,为什么我看订单的预定里的买家也发生了改变”

在订单上有两种买家信息,可以通过在不同的上下文中隔离来区别这两个拥有相同含义但却是不同词汇的词汇。在销售子域中建立两个上下文,分别为预定有界上下文和购买上下文,把订单领域模型拆分到这两个上下文中。在不同的上下文中,订单都有自己的买家信息,就解决了“在订单付款后改变了买家信息,为什么我看订单的预定里的买家也发生了改变”这个问题。

因为同名的业务词汇之间的关系不清楚导致的疑惑

“为什么我变更了profile 上的买家地址,订单上的买家地址就跟着改变了”

订单存在于购买上下文,profile 存在于身份信息上下文中,购买上下文和身份信息上下文存在映射关系,在订单创建时候从身份信息上下文复制买家地址,在订单中单独保存。这样就解决了“为什么我变更了profile 上的买家地址,订单上的买家地址就跟着改变了” 的问题。

引用:

  1. 《领域驱动设计》
  2. 《实现领域驱动设计》
  3. 当Subdomain遇见Bounded Context
  4. DDD的终极大招——By Experience
  5. 《领域驱动设计学习:领域、子域、限界上下文》

文/ThoughtWorks王岩

更多精彩洞见,请关注微信公众号:ThoughtWorks洞见

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容