第15章 精炼
上章我们讲到领域层被分割成一个个BOUNDED CONTEXT,构建出了CONTEXT MAP,并介绍了各个CONTEXT的关系。做任何事情,都要抓住主要矛盾,进行领域驱动设计也是。我们需要通过精炼,得到CORE DOMAIN(核心领域)。围绕核心领域展开分析。核心领域可能包含几个CONTEXT,也肯能只包含一个CONTEXT,甚至可能只是CONTEXT的一部分(如上章讲的SHARED KERNEL)。
精炼是把一堆杂乱在一起的组件分开的过程,以便通过某种形式从中提取出最重要的内容。就像蒸馏过程一样。精炼把最有价值的那部分提出取出来。这个部分使我们的软件区别于其他软件,并使整个软件产生价值。这个部分就是CORE DOMAIN。
精炼过程所分离出来的副产品也有一定的价值,比如本章将介绍的GENERIC SUBDOMAIN和COHERENT MECHANISM。
本章为了更好的说清楚各部分的关系,我将相关概念的顺序调整一下,不完全按照书中的顺序进行介绍。
15.1 如何提炼CORE DOMAIN
15.1.1找准方向
通过DOMAIN VISION STATEMENT(领域愿景说明) 和 HIGHLIGHTED CORE(突出核心),找准核心领域的提炼方向。
DOMAIN VISION STATEMENT(领域愿景说明)
下面展示了两个DOMAIN VISION STATEMENT的示例:
HIGHLIGHTED CORE(突出核心)
DOMAIN VISION STATEMENT从宽泛的角度对CORE DOMAIN进行了说明,但CORE DOMAIN到底包含哪些元素,不同的人会有不同的理解,甚至同一个人在不同的时间也会有不同的理解。所以我们需要创建一个单独的文档(精炼文档)来描述和解释CORE DOMAIN。精炼文档并不是完备的设计文档,简短一些(3-7页,每页内容不必太多),主要是要描述好CORE DOMAIN内各元素之间的关系。精炼文档是HIGHLIGHTED CORE(突出核心)的一种形式。
精炼文档应该能够被团队中的非技术人员理解。把它当作一个共享的视图,描述每个人都应该知道的东西,而且可以把它作为团队所有成员研究模型和代码的一个起点。开发人员通过精炼文档应该很容易分别出什么在核心领域内,什么在核心领域外。精炼文档要保证和CORE DOMAIN的一致。CORE DOMAIN发生变更后,要及时更新精炼文档。
15.1.2去粗取精
有时候,我们很难说明白哪部分属于核心领域,但是反过来,我们很容易说清楚,什么不属于核心领域。所以我们可以通过“去粗”来“取精”。
15.1.2.1 COHESIVE MECHANISM(内聚机制 )
15.1.2.2 GENERIC SUBDOMAIN(通用子领域)
把模型中起支撑作用的部分,提取出来,放在单独的MODULE中,这些部分就是GENERIC SUBDOMAIN(通用子领域)。GENERIC SUBDOMAIN的优先级低于CORE DOMAIN。通用不等同于可重用。我们应该将更多的精力放在CORE DOMAIN。GENERIC SUBDOMAIN只需保证服务好对应的CORE DOMAIN,不必服务于其他领域,所以不必执念于可重用。GENERIC SUBDOMAIN与COHESIVE MECHANISM的动机是相同的——都是为了CORE DOMAIN减负。区别在于二者所承担的职责的性质不同。GENERIC SUBDOMAIN是以CORE DOMAIN为基础的,表示如何看待领域的某个方面。在这一点上,他和CORE DOMAIN没什么区别,只是重要性和专门程度较低而已。COHESIVE MECHANISM并不表示领域,他的目的是解决CORE DOMAIN所提出来的一些复杂的计算问题。
具体的落地方面GENERIC SUBDOMAIN有4种实现思路。
思路1:现成的解决方案
有时可以购买一个已实现好的解决方案,或使用开源代码。
优点
缺点
思路2:公开发布的设计或模型
优点
缺点
思路3:把具体的实现外包出去
优点
缺点
比如在之前的项目中,我们把APP的开发全都外包了出去。因为APP只涉及到了数据的展示和收发,不涉及CORE DOMAIN的内容。
思路4:内部实现
优点
缺点
当然,“内部实现”也可以与“公开发布的设计或模型”结合起来使用。
GENERIC SUBDOMAIN是你充分利用外部设计专家的地方,这些专家不需要深入理解你特有的CORE DOMAIN,也不涉及CORE中的具体机密。随着时间的推移,CORE DOMAIN会不断变窄,越来越多的通用化的模型将作为框架被实现出来,或者至少被实现为公开发布的模型或分析模式。
15.1.2.3 SEGREGATED CORE(分离核心)
SEGREGATED CORE是对CORE DOMIAN 的进一步剥离。SEGREGATED CORE也起到了对CORE DOMIAN的支撑作用,但不是不像GENERIC SUBDOMAIN那样很容易识别出来,甚至代码包都是和CORE DOMAIN藕合在一起的。
具体分离方法上,基本上采用了和GENERIC SUBDOMAIN一样的原则,只是从另一个方向来考虑而已。那些在应用程序中非常关键的内聚子领域可以被识别出来,并分离到它们自己的内聚包中,如何处理剩下的那些难以区分的元素虽然也很重要,但其重要性略低。这些元素或多或少地可以保留在原先的位置,也可以放在包含了重要类的包中。最后,越来越多的剩余元素可以被提取到GENERIC SUBDOMAIN中。SEGREGATED CORE可以理解成从CORE DOMIAN分离出来的,向GENERIC SUBDOMAIN转化前的中间状态。此状态的有一部分可以转为GENERIC SUBDOMAIN,剩下的部分还处于SEGREGATED CORE状态。
15.2 对CORE DOMAIN进一步抽象
即使是CORE DOMAIN模型,其内部也可能会包含太多的细节,以至于它很难表达出整体的视图。我们需要采用ABSTRACT CORE 模型对其进行进一步的抽象,将模型中最基本的概念识别出来,并分离到不同的类、抽象类或接口中。设计这个抽象模型,能够表达出重要组件之间的大部分交互。把这个完整的抽象模型放到ABSTRACT CORE,而专用的、详细的实现类则留在子领域的CORE中。ABSTRACT CORE和子领域的CORE共同构成CORE DOMAIN。
提取ABSTRACT CORE并不是一个机械的过程,需要通过重构得到更深层的理解,而且往往需要大量的重新设计。如果项目中同时使用了ABSTRACT CORE和精炼文档,那么ABSTRACT CORE的最后结果看起来应该和精炼文档非常类似。当然ABSTRACT CORE使用代码编写的,因此更为完整。
15.3 如何管理CORE DOMAIN
我们一定要将CORE DOMAIN交给技术能力最强、最稳定的的团队或人员。他们需要不断积累和消化专业知识,并将这些知识转化为一个丰富的模型。很多团队喜欢把一些通用化的模块(而不是CORE DOMAIN)交给技术大牛,而往往技术大牛也乐于做这些工作。但是在领域驱动模式的开发方式下,这种工作的分配是不可取的。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!