区分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的更多相关文章

  1. DDD:Strategic Domain Driven Design with Context Mapping

    Introduction Many approaches to object oriented modeling tend not to scale well when the application ...

  2. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  3. DDD~Unity在DDD中的使用

    回到目录 上一讲介绍了DDD中的领域层,并提到下次要讲Unity,所以这篇文章当然就要介绍它了,呵呵,Unity是Microsoft.Practices中的一部分,主要实现了依赖注入的功能,或者叫它控 ...

  4. Repository在DDD中的应用

    Repository在DDD中的应用2014-10-09 08:55 by Jesse Liu, 98 阅读, 0 评论, 收藏, 编辑 概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值 ...

  5. Bounded Context

    From http://martinfowler.com/bliki/BoundedContext.html Bounded Context is a central pattern in Domai ...

  6. DDD中的聚合和UML中的聚合以及组合的关系

    UML:聚合关系:成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在.如汽车(Car)与引擎(Engine).轮胎(Wheel).车灯(Light)之间的关系为聚合关系,引擎.轮胎.车灯可以 ...

  7. DDD中限界上下文与通用语言的作用

    什么是通用语言 通用语言, 最主要的目的就是减少交流中信息丢失, 在实际开发中, 可能关联很多人, 例如有业务层面的业务细节制定者.领域专家.产品经理.项目经理 .架构师.开发经理.测试经理等等, 即 ...

  8. 对DDD中领域服务的理解

    CZ 能不能清晰具体区分service和实体的区别 网上有人用DCI来解决 不知道对不对 STST 我复习下DDD中的服务的概念了参与讨论啊CZ 这个我也看过 但是太过于笼统 STST STST 复习 ...

  9. Java实现DDD中UnitOfWork

    Java实现DDD中UnitOfWork 背景 Maintains a list of objects affected by a business transaction and coordinat ...

随机推荐

  1. .NET程序崩溃了怎么抓 Dump ? 我总结了三种方案

    一:背景 1. 讲故事 最近几天接到了几个crash的求助,可能这几个朋友没玩过怎么去生成dump,只能手把手教,感觉也不是一个办法,所以有必要总结一下,后续再有朋友咨询的话,我就可以把这篇文章丢过去 ...

  2. nginx 的基础知识(二)

    Nginx 多进程网络模型 进程模型 nginx启动后以daemon的方式在后台运行,后台进程包括一个master进程和多个worker进程 master进程主要作用,接收来自外界的信号:向各work ...

  3. Linux C 进程

    进程 UNIX编程手册第6 7章完结 24 25 26 27 28 未完待续,可能等到期末考试结束吧 目录 进程 基础知识 内存分布 命令行参数 环境列表 获得环境 修改环境 非本地跳转 内存分配 在 ...

  4. Java枚举类与注解详解——一篇文章读懂枚举类与注解详

    目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代码的 ...

  5. 实践指南-网页生成PDF

    一.背景 开发工作中,需要实现网页生成 PDF 的功能,生成的 PDF 需上传至服务端,将 PDF 地址作为参数请求外部接口,这个转换过程及转换后的 PDF 不需要在前端展示给用户. 二.技术选型 该 ...

  6. GO语言常用标准库02---os包

    package main import ( "fmt" "os" ) func main() { //获得当前工作路径(当前工程根目录) dir, err := ...

  7. BTC芯片介绍

    BTC芯片介绍 Innosilicon宣布全球第一和最佳的28nm比特币ASIC和参考矿机 A1Craft(也称为A1)是2013年世界上最好的BTC ASIC,这是比特币区块哈希算法的易于使用,定制 ...

  8. 英伟达TRTTorch

    英伟达TRTTorch PyTorch JIT的提前(AOT)编译Ahead of Time (AOT) compiling for PyTorch JIT TRTorch是PyTorch / Tor ...

  9. python_request 使用jsonpath取值结果,进行接口关联

    一.jsonpath的安装 pip   install  jsonpath 二.使用举例 import jsonpath d1={"token":"hjshdsjhdsj ...

  10. 计算机网络-vlan划分

    1.VLAN的划分 (1)基于端口的VLAN: 交换机A上的1,2端口和交换机B上的3,4端口构成一个VLAN. 交换机A上的3,4端口和交换机B上的1,2端口构成一个VLAN. (2)基于MAC地址 ...