业务领域分析&界限上下文

  我们通常说的领域,是指一个范围,一个界限。比如我们常说的学术领域,技术领域,医疗领域等等。

  而DDD领域是什么呢?在回答这个问题之前,我们需要知道DDD是干什么的。DDD是一种综合软件系统分析和设计的面向对象建模方法,旨在帮我们设计高质量的软件模型,是一种解决复杂中大型软件的一套行之有效的方式。那既然是用来解决软件问题,那自然要弄清楚软件系统的业务需求。

  以电商系统为例子,涉及到的主要是商品、用户、订单、支付、物流、售后相关业务。DDD中的领域也并没有什么特别之处,它只是被界限在指定的业务需求之中,有了更清楚的范围边界。其实也可以参照原著《领域驱动设计:软件核心复杂性应对之道》的总结: 

一个领域本质上可以理解为就是一个问题域,只要是同一个领域,那问题域就相同。所以,只要我们确定了系统所属的领域,那这个系统的核心业务,即要解决的关键问题、问题的范围边界就基本确定了。

  对于一个领域,我们往往会根据业务进行拆分,利用分而治之思想,把大而复杂的领域拆分成一个个子领域。进而有了核心域和子域的概念。

  接下来,我们的进销存系统来进行分析。

  我们的进销存系统包含供应商采购商品,商品成列销售,物流发货等,其本质也是电商系统,只是复杂程度远远不如天猫,京东这样的在线电商网站。根据实际业务,我们可以把系统拆分成 商品子域 用户子域 销售子域 订单子域 物流子域 日志子域 等等。

  那么我们现在来确定核心域是什么呢?商品?用户?其实电商的本质还是销售赚钱,说吧了还是做生意,少不了买卖。所以核心域还是销售子域。作为一个业务的核心存在,它最能体现系统的核心价值,也是核心竞争力。如果要最大化系统的价值,我们必然要在核心域的设计上更胜一筹。而我们系统的销售子域,具体是什么呢?就是把供应商的商品卖给商家,然后供应商直接给商家供货,目前阶段,供应商-》商家 是单向,二期就变成双向的了,就是说供应商也可能是商家,商家也可能是供应商,相互之间都可以买卖商品,这就是我们要解决的核心问题,也就是核心域,其他的子域都是为这个子域进行服务。确定核心域后,我们在进行开发设计的时候就有了主次之分。

  通用子域,顾名思义,也就是服务于整个业务领域。比如我们要为该网站提供一个日志系统,用来记录一些日志。我们可以设计一个日志子域来供其他子域使用。比如我们的审批流日志等等。

  支撑子域的作用于业务系统的某些重要业务而非核心业务,它关注于业务的某一方面,来支撑完善业务系统。比如我们的送货单子域,属于物流的范畴。

  领域总结:领域是有范围界限的,也可以说是有边界的;核心域是业务系统的核心价值所在,承载着一个系统的重中之重;通用子域可以理解为业务系统所有子域的消费者,提供着通用服务;支撑子域专注于业务系统的某一重要的业务,来支撑和完善业务系统。

  接下来再来说话界限上下。

  在通用语言章节,上文领域都提到划分界限,这个在DDD中就是界限上下文。(圣杰总结的真的很好)

  根据上文对领域的剖析,我们把系统主要拆分成几个子域,其中销售子域是核心域,商品子域和物流子域为支撑子域。在这三个子域中,都要和商品打交道。如果把商品抽象为Product对象的话,按我们一般的常规思路(抛开子域的划分)来说,不管是商品销售还是发货,我们都可以共用同一个Product对象。
  但在DDD中,在商品子域和销售子域中,可以共享这个Product对象,但在物流子域,系统送货单子域,就有点大材小用。为什么呢?因为毕竟货单子域关注的是订单商品的收发货状态。针对发货流程而言,我只关心商品的数量、大小、重量等规格,而不必了解商品的价格等其他信息。所以说送货单子域应该关注的是货物的发货处理而不是商品。
  那为什么我们之前的开发思路会共用同一个Product对象呢?答案很简单,没有进行领域的划分。把整个项目一概而论,统一建模导致的结果。
在DDD的思想下,当划分子域之后,每个子域都对应有各自的上下文。在销售子域和商品子域所在的上下文语境中,商品就是商品,无二义性。在物流子域的上下文语境中,我们也可以说商品的发货处理,但这时的商品就特指货物了。确定了真实面目之后,我想我们也会不由自主的抽象一个新的物流对象来处理物流相关的业务。这也是DDD带来的好处,让我们更清晰的建模。商品领域对象和物流对象解耦,如果有业务调整,增删属性字段,相互之间不影响。

  用官话来说限界上下文主要用来封装通用语言和领域对象。
       个人的理解它就是用来为领域提供上下文语境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。

 

 

  

 

posted @ 2019-06-17 16:32  yizuoming  阅读(1271)  评论(0)    收藏  举报