区分DDD中的Domain, Subdomain, Bounded Context, Problem/Solution Space
区分DDD中的Domain, Subdomain, Bounded Context, Problem/Solution Space
译自: Domain, Subdomain, Bounded Context, Problem/Solution Space in DDD: Clearly Defined
领域驱动设设计是一种设计系统的方式,强调在领域专家和系统建造者之间创建一个通用的语言。著名的DDD原则包括:使用通用语言和确定隐性和显性。
DDD中的有些概念并没有明确的定义,且高度隐晦。每个人对域(Domain), 子域(Subdomain), 问题空间(Problem Space)和解决空间(Solution space)都有不同的理解。本文将会对这些概念进行澄清。
本文基于GitHub上的一个会话,参与会话的很多人都来自DDD社区。
模糊但没有歧义
在开始定义术语之前,我想强调Kenny Baas-Schwegler 提出的一个重要观点。他强调DDD应该是模糊的。由于DDD的模糊性,我们可以用它来探索、建模和解决新问题(现有的DDD模式和准则并没有限制我们的思维方式)。
模糊性意味着可以用一个词来描述在某些方面相似但并不相同的不同事物。例如"few",在一些场景下,它表示的范围可能是2-3,而在其他场景下可能表示不同的范围, 如5-10。关于模糊性最主要的是可以通过上下文进行推断(如果不同的人以截然不同的方式解释它,那就太模棱两可了)。
如果我说出一个词,期望对方能给出相同的定义,但对方实际上理解的是另一种定义,则说明没有对齐定义(即我们认为正在讨论同一件事,但实际上并不是)。

使用DDD时,我们希望拥抱模糊性,但同时也希望对每个概念的模糊程度有共同的理解。
以下的定义都比较模糊,但当我们使用这些词时,能够对齐对它们的认知。
Domains
DDD对领域的定义与剑桥字典中的定义非常类似:
上面对领域的定义非常模糊。什么是一个感兴趣的领域?有可能是任何事情。一个领域实际上是围绕某些概念的子集的任意边界。

How to group these concepts into domains?
如果使用彩色形状来表示概念,那么应该如何对它们进行领域划分?如你所想,实际存在很多划分的方式。
我们可以把方形放到方形领域,那圆形放到圆形领域。但蓝色方形和蓝色圆形也可以归属为蓝色领域。

The same concepts can belong to different domains
当对系统进行建模时,我们可以选择最合适的领域边界来使得软件和组织边界保持一致。即使我们选择按照颜色来对齐领域,但形状领域仍然存在。
在我参与的每个建模领域以及每个建模研讨中,不同的人都倾向于跨不同领域边界来分割系统。这是正常的,应该根据实际情况拥抱模糊性,并运用设计思维。
Subdomains
域和子域有什么区别?这个问题比较简单,子域并不是字典中的一个单词(domain存在于字典中,但subdomain不存在...)。子域在web世界中占有重要的位置,但在DDD中意味着什么?
在DDD中,一个子域是一个相对的概念。域和子域可以交互使用。当我们使用子域时,我们强调将该域作为另一个已经确定的更高级域的"孩子"。
因此,每个子域也是一个域,且大部分域都是子域。当我们的模型不包含更高级别的父域时,才不会将一个域认为是子域。
Core, Generic, Supporting (Sub)Domains
当听到一个核心域实际是一个子域时,很多人通常会感到困惑。在Eric Evans 的书中,他将领域称为核心域,但有时也会称之为子域。
你可以将域和子域认为是DDD中的模糊性之一,子域同时也是域,使用核心域还是子域并不重要,它们在概念上是模糊的,但并没有歧义。
核心域听起来更好,而核心子域则强调它属于一个更高级别的域。
Problem Space vs Solution Space: 更好的DDD模型
让人最困惑的是问题空间和解决空间。每个人对DDD上下文中的问题空间和解决空间都有不同的看法
我认为使用问题/解决空间模型太过简单,无法完整地传达DDD所要表达的内容,Simon Wardley的战略圆形则更加形象。

Simon Wardley’s Strategy Cycle
在上图中有如下元素:
- Purpose:我们关心的领域中存在哪些问题需要解决或需要达到什么目的?
- Landscape:我们关心的领域的当前状态是什么?
- Climate:领域的推动力是什么?我们该如何演进?
- Doctrine:我们应该普及的好的做法。
- Leadership:在现有和新领域中我们应该做出什么样的方案或变动。
Domains/Subdomains Problem 还是Solution Space?
除非我们可以明确定义问题或解决空间,否则无法对该问题做出回答。
当前的系统中包含(子)域,而(子)域中存在又会存在用户需求和相关问题。对这些需求和问题的解决会涉及多个(子)域,并会修改(包含子域的)系统状态。因此逻辑上所有的空间都会包含(子)域。
那么在决定为哪个子域设计解决方案时,是否存在仅存在于问题空间的子域?这样,一些域只需要与解决相关,而与问题无关。
从下图的例子中可以看到,是可以将一些子域作为单一的问题空间或解决空间,但没有必要这么做,应该采用更确切的方式对业务进行划分。

My understanding of problem and solution space in DDD. There are many other definitions out there.
新的解决方案也会带来新的问题,或正如Simon Wardley所说:高阶系统创造了新的价值来源。
我建议尽量避免使用问题空间,而应该准确地指出你所要表达的内容:purpose, landscape, climate, doctrine, leadership等。
无论何时,当用到术语"问题空间"和"解决空间"时,都需要阐明你所讲的观点。你的问题空间也是别人的解决空间,只是看的角度不同而已。
在作者的理解中,问题空间就是针对使用者来说,存在问题的地方;而解决空间就是针对提供解决方案的人来说,落地方案的地方。问题空间和解决空间只是不同人的不同视角而已。
领域是分层的
如果一个域可以包含子域,而子域又可以作为一个域,那么子域就可以包含更多细粒度的子域。域和子域是层级概念。
当设计社会技术系统时,通常我们会希望将域放到不同层级。一个组织的领导者可能会希望看到公司的7个顶级域。软件架构师可能会希望看到100个微服务的领域边界。
企业架构中会在不同层级用到业务能力的概念。业务能力可以看作是域或子域

Domains are hierarchical and they represent business capabilities
Subdomain vs Bounded Context
这是DDD中另一组可能让人混淆的概念,但如果明确了解了子域的定义,就非常容易解释。
我们已经得出,子域是一个非互斥的,任意概念的集合。而一个边界上下文是一个模型的边界,代表了模型的概念,关系和规则。相同的子域可能由无数模型构成。
DDD中的模型的表达方式多种多样,如便签或代码,以及任何展示领域概念,关系和规则的事物。
由于一个边界上下文是一个模型的边界,它可能包含来自多个子域的概念(如跨多领域的规则),或者可以将单个子域建模为多个边界上下文(如子域中的各个逻辑处理单元)。

Subdomains vs Bounded Contexts: Areas of the domain vs boundaries of models of the domain
区分DDD中的Domain, Subdomain, Bounded Context, Problem/Solution Space的更多相关文章
- DDD:Strategic Domain Driven Design with Context Mapping
Introduction Many approaches to object oriented modeling tend not to scale well when the application ...
- 初探领域驱动设计(2)Repository在DDD中的应用
概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...
- DDD~Unity在DDD中的使用
回到目录 上一讲介绍了DDD中的领域层,并提到下次要讲Unity,所以这篇文章当然就要介绍它了,呵呵,Unity是Microsoft.Practices中的一部分,主要实现了依赖注入的功能,或者叫它控 ...
- Repository在DDD中的应用
Repository在DDD中的应用2014-10-09 08:55 by Jesse Liu, 98 阅读, 0 评论, 收藏, 编辑 概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值 ...
- Bounded Context
From http://martinfowler.com/bliki/BoundedContext.html Bounded Context is a central pattern in Domai ...
- DDD中的聚合和UML中的聚合以及组合的关系
UML:聚合关系:成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在.如汽车(Car)与引擎(Engine).轮胎(Wheel).车灯(Light)之间的关系为聚合关系,引擎.轮胎.车灯可以 ...
- DDD中限界上下文与通用语言的作用
什么是通用语言 通用语言, 最主要的目的就是减少交流中信息丢失, 在实际开发中, 可能关联很多人, 例如有业务层面的业务细节制定者.领域专家.产品经理.项目经理 .架构师.开发经理.测试经理等等, 即 ...
- 对DDD中领域服务的理解
CZ 能不能清晰具体区分service和实体的区别 网上有人用DCI来解决 不知道对不对 STST 我复习下DDD中的服务的概念了参与讨论啊CZ 这个我也看过 但是太过于笼统 STST STST 复习 ...
- Java实现DDD中UnitOfWork
Java实现DDD中UnitOfWork 背景 Maintains a list of objects affected by a business transaction and coordinat ...
随机推荐
- 基于pyqt5和openpyxl和Pyinstaller的青年大学习检查未学习人数的脚本
前几天接到团支书的一个需求,因为学校给的名单是青年大学习已学习的名单,然而要知道未学习的名单只能从所有团员中再排查一次,过程相当麻烦.团支书跟我抱怨后,刚好我也学过一些操作办公软件的基础.打包pyth ...
- linux系统开机自动挂载光驱 和 fstab文件详解
Linux 通过 UUID 在 fstab 中自动挂载分区 summerm6关注 2019.10.17 16:29:00字数 1,542阅读 607 https://xiexianbin.cn/lin ...
- Jinja2模板概述
例子一 循环语句 [root@m01 ~]# cat upstream.conf upstream web { {% for i in range(1,11) %} server 172.16.1.{ ...
- 把采集到的数据发送到一个Google Docs或者Google Form上 这个网站提供了参考和例子
把采集到的数据发送到一个Google Docs或者Google Form上这个网站提供了参考和例子 http://www.instructables.com/id/Post-to-Google-Doc ...
- sizeof()用法汇总-(转自风雷)
sizeof()功能:计算数据空间的字节数 1.与strlen()比较 strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素. ...
- Jenkins 基础篇 - 任务创建
前面了解了 Jenkins 上各种任务的区别后,我们就来实践应用下,先创建一个[文件夹]类型的任务,将我们目前的一些基础的演示任务[移动]到文件夹里面去,这样可以先做个简单的分类. 新建一个[文件夹] ...
- VMware vRealize Network Insight 6.2 发布 - 网络和安全可视化分析
发现.优化应用安全性和网络连接解决方案并对其进行故障排除 VMware vRealize Network Insight 可帮助您跨混合和多云环境构建经过优化且高度可用的安全网络基础架构.它提供了网络 ...
- 通过CSS设计模式搭建自己系统的CSS架构
theme: qklhk-chocolate 传统的CSS书写风格是随意命名,堆叠样式,造成了混乱不堪的结果,复杂页面的样式书写通常会出现几百行甚至上千行的代码,CSS设计模式在实际应用中的横空出世拯 ...
- Python3.6 的字典为什么会快
作者:青南链接:https://zhuanlan.zhihu.com/p/73426505来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 在Python 3.5(含)以 ...
- Java读取SQL server数据库
要打开SQL server 的三个服务,然后再执行代码. package com.sql; import java.sql.SQLException; import java.sql.Statemen ...