模型设计,DDD 分两阶段,战略设计和战术设计。
战略设计的子域、限界上下文和上下文映射图等概念大致分为:
首先需要明确:
我们要解决的问题就是领域问题,相关概念如,子域、核心域、支撑域、通用域等。其实都是:如何分解问题。
领域(Domain)是一号位,对应待解决的问题。解决问题通常思路是分而治之,DDD就把一个大领域分解成若干小领域(子域(Subdomain))。
DDD首先要建立起一套通用语言,拥有一致的业务词汇表,它们对应模型。 接着,要分类词汇,即把它们划分到不同子域。关键就是分离关注点。
比如,做个项目管理软件,就要有用户、项目、团队,不同人还要扮演不同角色。 第一步,至少先分开身份管理、项目管理,因为关注点不同:
这就有了俩子域:身份管理,项目管理。
若直接给结果,你可能会觉得很好理解。但划分出不同子域还是容易出问题的,因为有些概念不易区分。 比如,用户应该怎么划分?放在身份管理是合适的,但项目管理也要用到呀!
根据单一职责原则,它给了我们一个重要思考维度,变化从何而来? 不同角色的人关注不同变化,所以,虽然我们用的词都是“用户”,但想表达的含义其实不同,最好分开这些不同的含义,即分开不同角色:
DDD问题层面的概念已经阐述完毕。接下来,就是解决方案层面。
切分出的子域,怎样落实到代码? 首先要解决的就是这些子域如何组织?
这就引出DDD的
限定了通用语言自由使用的边界,一旦出界,含义便无法保证。 比如,同样是“订单”,不加限制,很难区分它在哪种场景。一旦定义了限界上下文,那交易上下文的“订单”和物流上下文的“订单”肯定不同。就是因为订单这个说法,在不同边界内,含义不同。
注意,子域和限界上下文不一定是一一对应的,可能在一个限界上下文中包含了多个子域,也可能在一个子域横跨了多个限界上下文。
限界上下文是在解决方案层面,所以,就可以把限界上下文看作一个独立系统。限界上下文与微服务的理念契合,每个限界上下文都可成为一个独立服务。
限界上下文是完全独立的,不会为了完成一个业务需求要跑到其他服务中去做很多事,这恰是很多微服务出问题的点,比如一个业务功能要调用很多其他系统功能。
有限界上下文,就可以把整个业务分解到不同的限界上下文中,但是,尽管我们拆分了系统,它们终究还是一个系统,免不了交互。 比如:
我们要通过某种途径让订单上下文的一些信息发送到支付上下文。所以,要有一种描述方式,描述不同限界上下文之间交互的方式-上下文映射图(Context Map)。 DDD 给我们提供了一些描述这种交互的方式,比如:
这么多交互方式,主要是为让你在头脑中仔细辨认,看看限界上下文之间到底在以怎样的方式交互。
知道不同限界上下文之间交互方式后,不同交互方式就可落地为不同协议。 常用协议如:REST API、RPC 或是 MQ, 按需选型即可。
在我们定义好不同的限界上下文,将它们之间的交互呈现出来之后,就得到了一张上下文映射图。 上下文映射图是可以帮助我们理解系统的各个部分之间,是怎样进行交互的,建立全局性认知。