最近在看Vaughn Verron著的《实现领域驱动设计》这本书,对于以前只接触过MVC,没接触过DDD、微服务项目的我来说,学习DDD(Domain-Driven Design)算是一种设计思想上的跳跃了,书中的概念和概念之间的关系理解起来比较吃力,因此就很有必要写篇文章梳理一下了。

我首先画了个思维导图表示大小概念之间的关系:

图1:思维导图01

1、领域

这里引用北理工金旭亮老师的解释,感觉比较通俗易懂:“领域与具体开发技术无关。就是你的软件系统要解决的实际问题相关的所有东西的集合。比如你要开发一个卖书的网上卖书系统,那么如何进货,如何决定优惠规则,如何安排物流,如何管理客户级别,如何分析销售数据等等,这直接与业务相关的所有东西都归属于“领域”。DDD就是说你得先把领域中涉及到的数据、流程、商业规则等都弄明白了,然后以面向对象的观点为其建立一个模型(领域模型),再选用合适的软件技术去实现这个模型”。

领域中存在问题空间和解决方案空间。问题空间是领域的一部分,对问题空间的评估应该同时考虑已有子域和额外所需的子域,因此,问题空间是核心域和其他子域的组合。解决方案空间包括一个或者多个限界上下文,即一组特定的软件模型。这是因为限界上下文本身就是一个特定的解决方案。对于子域和限界上下文的概念参照后文。

2、子域

还是得有图有真相,先祭出一张书中原图:

图2:一个抽象的业务领域

在书中,子域是领域更细粒度的划分,根据重要性与功能将领域分为大致三类(视项目实际情况而定)的多个子域,分别是核心子域、支撑子域和通用子域。核心域是业务成功的主要促成因素,主要竞争力,支撑子域是支撑核心域的,而通用子域是业务系统的公用部分。从图2中我们可以看出,支撑子域在领域中是可以有多个的,核心域应该是只有一个为好,当然,除了核心域外,其他子域也可以没有(个人感觉这种情况应该很少)。

核心域是最重要的,书中也告诉我们开发核心域的解决方案是一种关键性的业务的投入,应该给予核心域的开发最高的优先级和最优秀的开发团队。如果核心域中的一些功能可以从核心域中分离出来,那我们可以用模块的形式从核心域分离出来,这里说的模块其实就是java中说的包,也可以理解为命名空间,文件夹(这大概是最通俗的说法了)。

3、限界上下文

限界上下文包含的是一个系统、一个应用、一种业务服务以及一系列实现业务的复杂组件。

比如说在一个电子商务服务系统的领域中,加入一个库存系统和一个外部的预测系统,那么这个领域就可以拥有对应的三个限界上下文,一个限界上下文可能被包含在一个子域里,也可能多个子域,比如电子商务系统就包含了发票子域、订单子域等。

通用语言:

可以把限界上下文看成是整个应用程序之内的一个概念性边界。这个边界内还有一个很重要的概念叫通用语言,限界上下文中的每种领域术语、词组、或者句子都叫做通用语言,无论是领域专家和开发人员在对领域问题的沟通、需求的讨论,开发计划的制定、概念、还是代码中出现的类名与方法,都包括其中,而且要注意的一个规则是:只要是相同的意思,就应该使用相同的词汇。可以看出,这种通用语言不是一下子就可以形成,而是在一个各方人员的讨论中,不断发现、明确与提炼出来的。关于限界上下文中的术语一定要准确反映通用语言的问题,有一篇博文说得很易懂:驱动设计整理-概念&架构

领域模型:

限界上下文是一个显示的边界,领域模型便存在于这个边界之内。领域模型其实就是把通用语言表达成软件模型,领域模型包括了模块、聚合、领域事件和领域服务等概念,这篇文章暂不对这些概念作解释。但是要知道限界上下文并不只局限于容纳模型,一个应用或一种业务服务。有时,限界上下文所包含的内容可能它通常标定了一个系统、较少,比如,只在一个通用子域的范围内,那么它便可以只包含领域模型。

关于限界上下文还有一些问题需要解答:

1、限界上下文怎么命名?

答:模型名+“上下文”。

2、子域和限界上下文的对应?

答:最好是将子域一对一地对应到限界上下文。因为这种做法显示地把领域模型分离到不同的业务板块中,并将问题空间与解决方案空间融合在一起。

参考资料:

1、《实现驱动领域设计》

2、如何DDD?

3、理解限界上下文

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐