一、什么是精炼
一般都知道,做一个大型设计甚至一个超大型设计(虽然一般人无法经历,但做一个稍大些的设计一对比就会有所明白),从中准确抓住核心领域是非常困难的。即使是通过某种手段确定了核心领域后,核心领域的复杂性仍然是让众多人感到无所适从。这正如寻找铁矿,找到就很困难,找到后开采同样是一个复杂的问题。而把开采后的铁矿石提炼是全世界一种通行的做法。同样,这个道理也适应于领域驱动,领域的复杂性要求人们不得不对其进行精炼。
什么是精炼?“精炼是把一堆混杂在一起的组件分开的过程,以便通过某种形式从中提取出最 重要的内容,而这种形式将使它更有价值,也更有用。模型就是知识的精炼。通过 每次重构所得到的更深层的理解,我们得以把关键的领域知识和优先级提取出来。”其实再次一个更形象的例子,日常女孩子们喜欢的金首饰,就分纯金,足金,千足金,万足金。可能对大多数物品精炼到一定程度就没有更多的意义了。但是对于某些特定物品,当精炼到某种程序后,就出现了神奇的物理现象,这些是精炼的意义所在。
根据实际情况,是精炼到一定的程度就停止(比如程序的稳定性,到几个九就可以了),还是不断的精炼下去,达到质变的一个临界点。
二、精炼的内容和步骤
精炼的主要内容包括以下几点:
1、帮助所有团队成员掌握系统的总体设计以及各部分如何协调工作
2、找到一个具有适度规模的核心模型并把它添加到通用语言中,从而促进沟 通
3、指导重构
4、专注于模型中最有价值的那部分
5、指导外包、现成组件的使用以及任务委派。
那么精炼是如何进行的呢?一般来说分为以下几步:
1、编写DOMAIN VISION STATEMENT(领域愿景说明)和HIGHLIGHTED CORE(突出核心)
2、分离通用子领域
3、重新打包SEGREGATED CORE
4、ABSTRACT CORE(抽象内核),用纯粹的形式表示了最基本的概念和关系
这些方法步骤并不是要求按顺序进行的,它们对整个精炼起到的作用和需要付出的代价也各有不同,大家可以在实际情况中根据需求来结合使用。
三、精炼的模式
精炼有以下几种模式,可能通过这些模式来对精炼进行把控:
1、CORE DOMAIN(核心领域)
这个其实非常容易理解,就是抓住重点,抓住核心。在面对需求时,无论是设计模型还是设计架构,都会有一个让设计者头痛的事,那就是从哪入手,解决什么?用什么解决?先后顺序重点在哪儿?所以说,最核心的领域往往会被一些表面强烈的需求给掩盖。所以更要从领域视图的整体来分析,达到人尽其用,资源匹配。
因此,对模型的提炼是不可避免的。要通过某些具体的技术或者手段来找到CORE DOMAIN,这种精炼的过程是迭代的,设计得的认知可能也会不断的演进。一开始的认知可能会发生变化甚至相反。要保证让最优秀的人才来开发最核心的领域。
在此之后,需要选择核心,即重点针对那些能够表示业务领域并解决业务问题的模型部分。可以通过专业的开发人员和业务领域的专家共同来对此进行抽象分析,从而更加专注于核心领域。
2、GENERIC SUBDOMAIN
领域模型设计中,各种细节导致整个设计复杂性和难度不断提高。设计者往往在其面前舍本逐末,在一些非核的领域上耗费了大量的精力。
3、DOMAIN VISION STATEMENT
愿景描述,这个其实就是一个整体的沟通文档,“它关注的重点是领域 模型的本质,以及如何为企业带来价值。”这个文档要尽量精简,尽量兼顾各方的利益。它可以作为一个行动指南,帮助团队在精炼模型的过程中保持共同的方向。所以本模式就是要识别核心领域,并将其单独放到专门的模块中,将无关的细节和其它领域放到非优先级。
这里有一个重要的问题,通用并不意味着复用。要关注精炼的“基本动机——我们应该尽可能把大部分精力投入到CORE DOMAIN工作 中,而只在必要的时候才在支持性的GENERIC SUBDOMAIN中投入工作。”
4、HIGHLIGHTED CORE
这种模式是一种比较简单和轻量化的解决领域划分的手段。它不会引起剧烈的变化和对模型的改动。可以通过突出核心(HIGHLIGHTED CORE),来将文档精炼,只保留重要的细节,其它不相关的非Core领域和元素的交互细节全部删除。精炼文档需要团队密切合作,不断沟通完善。消除使用这种模式的问题即:
1)文档可能无法维护
2)文档可能无人阅读
3)文档可能教会法简化复杂性的目的。
5、COHESIVE MECHANISM
内聚机制,此机制最大的用途在于“用途最大的地方是它通过一个INTENTION-REVEALING INTERFACE来提供访问,并且具有概念上一致的ASSERTION和SIDE-EFFECT-FREE FUNCTION。利用这些MECHANISM和柔性设计,CORE DOMAIN可以使用有意义的声 明,而不必调用难懂的函数。但最不同寻常的回报来自于使CORE DOMAIN的一部分 产生突破,得到一个深层模型,而且这部分核心领域本身成为了一种语言,可以灵活且精确地表达出最重要的应用场景。”
在设计中往往通过封装来实现内聚,但封装有时候儿会导致设计的膨胀,为了包容万物,封装会不断的增加新的模块。那么可以使用内聚机制来实现对领域的重新划分。
GENERIC SUBDOMAIN与COHESIVE MECHANISM二者的动机相同,目的均是精简CORE DOMIN。前者是以描述性的模型作为基础的,它用这个模型表示出团队会如何看待领域的某个方面。后者并不表示领域,目的是解决描述性模型说提出来的一些复杂计算问题。
6、SEGREGATED CORE
分离领域的目的,其实就是更好的实现内聚性,减少同其它领域的交互,降低耦合性。分离领域,目的一定是找出最核心的领域,而不是盲目的去分离。只有找到最核心的领域,把其它相关的领域分离开来,才能更好的实现模型对领域的清晰的描述。
实现它有以下几个步骤:
1)找到一个CORE子领域
2)将相关类转移至新Model中并依此对这些类的相关概念命名模块
3)重构代码,分离不直接表示概念的数据和功能
4)迭代(对SEGREGATED CORE MODEL)进行重构,使其中的关系和交互变得简单、表达更清除
5)继续迭代其它的CORE子领域
使用这种模式要有代价的,可能会使某些核心领域的关系变得复杂和更难以明白,这就需要一些具体的取舍。
7、ABSTRACT CORE
抽象,就意味着可以依赖。而可以依赖,就意味着可以重用。所以,在精炼的过程中,繁杂的细节会干扰设计人员的思维,而把领域精简细小化,则更利用领域的认知和应用。但过多的领域往往又会造成其之间相互的交互的复杂性。这时,抽象就可以应用了,把这些小的领域抽象出基本的接口来,大家都依赖于这个接口,再辅助以各种类和模块来实现各种详细的功能,这样就可以更好的精炼相关的领域。
对整体上进行精炼后,可以继续向深层精炼推进,也就是对各个子领域或者关键领域继续进行精炼,不断的抽象使得元素变得更简单更容易组合使用。
四、总结
西方的炼金士为了寻找便宜获得黄金的方法花费了几个世纪来处理各种材料,其实用现代的眼光看就是混合精炼的过程。如今的软件设计和软件编程,其实就是类似这个过程的。现如今需求海量,各种单一解决问题的手段和方法,往往都不能起到决定性的效果,所以把各种技术领域有机结合在一起,才是解决问题的王道。当从设计的角度来看解决问题后的整体设计时,就可以回望到精炼的这个过程。学习和实践就是一个否定之否定的不断的演进的过程。