上面这4个方程式,再加上其中的术语定义,以及它们所依赖的数学体系,表达了19世纪经典电磁学的全部内涵。
如何才能专注于核心问题而不被大量的次要问题淹没呢?LAYEREDAR CHITECTURE可以把领域概念从技术逻辑中(技术逻辑确保了计算机系统能够运转)分离出来,但在大型系统中,即使领域被分离出来,它的复杂性也可能仍然难以管理。精炼是把一堆混杂在一起的组件分开的过程,以便通过某种形式从中提取出最重要的内容,而这种形式将使它更有价值,也更有用。模型就是知识的精炼。
领域模型的战略精炼包括以下部分:
(1) 帮助所有团队成员掌握系统的总体设计以及各部分如何协调工作;
(2) 找到一个具有适度规模的核心模型并把它添加到通用语言中,从而促进沟通;
(3) 指导重构;
(4) 专注于模型中最有价值的那部分;
(5) 指导外包、现成组件的使用以及任务委派。
此图说明,通过战略精炼提炼核心模型的几种方式,下面分别详细看下。
CORE DOMAIN是系统中最有价值的部分。需要对模型进行提炼。找到CORE DOMAIN并提供一种易于区分的方法把它与那些起辅助作用的模型和代码分开。最有价值和最专业的概念要轮廓分明。尽量压缩CORE DOMAIN。让最有才能的人来开发CORE DOMAIN,并据此要求进行相应的招聘。在CORE DOMAIN中努力开发能够确保实现系统蓝图的深层模型和柔性设计。
选择核心
对CORE DOMAIN的选择取决于看问题的角度。
一个应用程序的CORE DOMAIN在另一个应用程序中可能只是通用的支持组件。尽管如此,仍然可以在一个项目中(而且通常在一个公司中)定义一个一致的CORE。像其他设计部分一样,人们对CORE DOMAIN的认识也会随着迭代而发展。开始时,一些特定关系可能显得不重要。而最初被认为是核心的对象可能逐渐被证明只是起支持作用。
工作分配
在项目团队中,技术能力最强的人员往往缺乏丰富的领域知识。这限制了他们的作用,并且更倾向于分派他们来开发一些支持组件,从而形成了一个恶性循环——知识的缺乏使他们远离了那些能够学到领域知识的工作。
如何良性的进行分配呢?
建立一支由开发人员和一位或多位领域专家组成的联合团队,其中开发人员必须能力很强、能够长期稳定地工作并且对学习领域知识非常感兴趣,而领域专家则要掌握深厚的业务知识。
介绍各种精炼技术。如下:
1)DOMAIN VISION STATEMENT(领域愿景说明):需很少的投入,它传达了基本概念以及它们的价值。
2)HIGHLIGHTED CORE(突出核心): 可以增进沟通,并指导决策制定,这也只需对设计进行很少的改动甚至无需改动。
3)GENERIC SUBDOMAIN(通用子域):通过重构和重新打包显式地分离出通用子域。
4)COHESIVE MECHANISM(封装原理):保持设计的通用性、易懂性和柔性。
5)SEGREGATED CORE(分离核心):重新打包出一个SEGREGATED CORE(分离的核心),可以使这个CORE清晰可见
(即使在代码中也是如此),并且促进将来在CORE模型上的工作。
6) ABSTRACT CORE(抽象内核): 用纯粹的形式表示了最基本的概念和关系(因此,需要对模型进行全面的重新组织和重构)。
模型中最普通的那些部分分离出去,它们就是GENERIC SUBDOMAIN(通用子领域)。GENERIC SUBDOMAIN与CORE DOMAIN形成鲜明的对比,使我们可以更清楚地理解它们各自的含义。
识别出那些与项目意图无关的内聚子领域。把这些子领域的通用模型提取出来,并放到单独的MODULE中。任何专有的东西都不应放在这些模块中。把它们分离出来以后,在继续开发的过程中,它们的优先级应低于CORE DOMAIN的优先级,并且不要分派核心开发人员来完成这些任务(因为他们很少能够从这些任务中获得领域知识)。
当开发这样的软件包,有以下几种选择:
1)有时可以购买一个已实现好的解决方案,或使用开源代码。
2)参考别人公开发布的设计或模型。当有一个被广泛使用的模型时,如《分析模式》[Fowler 1996]一书中所列举的那些模型(参见第11章),这种方法最为有效。
3)把实现外包出去。
4)内部团队成员实现。
其实,通用子域的实现,并非是从这些选择里面选择一个,而是根据实际情况,去选择多个,例如现在需要依赖短信服务,其作为一个通用子域,就需要购买解决方案外加内部开发人员进行对接开发。
很多项目团队都会编写“愿景说明”以便管理。最好的愿景说明会展示出应用程序为组织带来的具体价值。
DOMAIN VISION STATEMENT就是模仿这类文档创建的,但它关注的重点是领域模型的本质,以及如何为企业带来价值。在项目开发的所有阶段,管理层和技术人员都可以直接用领域愿景说明来指导资源分配、建模选择和团队成员的培训。如果领域模型为多个群体提供服务,那么此文档还能够显示出他们的利益是如何均衡的。
DOMAIN VISION STATEMENT可以用作一个指南,它帮助开发团队在精炼模型和代码的过程中保持统一的方向。团队中的非技术成员、管理层甚至是客户也都可以共享领域愿景说明(当然,包含专有信息的情况除外)。
目前,我司也有每个应用的愿景,但是还没有细化到具体的领域模型这块,看来还得继续完善啊,愿景确实能让大家在思想上达成高度一致,并且可以保持这对愿景的憧憬和为了实现最终愿景的奋斗意识。
突出核心作为一个方式,可以通过简短的文档描述以及在文档上标记,用来表明出模型里面最核心的部分,让人一目了然。
编写一个非常简短的文档(3~7页,每页内容不必太多),用于描述CORE DOMAIN以及CORE元素之间的主要交互过程。
把模型的主要存储库中的CORE DOMAIN标记出来。使开发人员很容易就知道什么在核心内,什么在核心外。
概念上的COHESIVE MECHANISM(内聚机制),可以分离一些复杂的算法或者公式,到一个单独的轻量级框架中。要特别注意公式或那些有完备文档的算法。用一个INTENTION-REVEALING INTERFACE来暴露这个框架的功能。现在,领域中的其他元素就可以只专注于如何表达问题(做什么)了,而把解决方案的复杂细节(如何做)转移给了框架。
然后,这些被分离出来的机制承担起支持的任务,从而留下一个更小的、表达得更清楚的CORE DOMAIN,这个核心以更加声明式的方式通过接口来使用这些机制。
GENERIC SUBDOMAIN(通用子域)与 COHESIVE MECHANISM(内聚机制)的区别?
GENERIC SUBDOMAIN与COHESIVE MECHANISM的动机是相同的——都是为COREDOMAIN减负。
区别在于二者所承担的职责的性质不同。GENERIC SUBDOMAIN是以描述性的模型作为基础的,它用这个模型表示出团队会如何看待领域的某个方面。在这一点上它与CORE DOMAIN没什么区别,只是重要性和专门程度较低而已。COHESIVE MECHANISM并不表示领域,它的目的是解决描述性模型所提出来的一些复杂的计算问题。
通过重构得到SEGREGATED CORE的一般步骤如下所示:
就像很多战略设计决策所要求的一样,创建SEGREGATED CORE需要整个团队一致行动。这一行动需要团队的一致决策,而且团队必须足够自律和协调才能执行这样的决策。困难之处在于既要约束每个人使其都使用相同的CORE定义,又不能一成不变地去执行这个决策。由于CORE DOMAIN也是不断演变的(像任何其他设计方面一样),在处理SEGREGATED CORE的过程中我们会不断积累经验,这将使我们对什么是核心什么是支持元素这些问题产生新的理解。我们应该把这些理解反馈到设计中,从而得到更完善的CORE DOMAIN和SEGREGATED CORE MODULE的定义。
这意味着新的理解必须持续不断地在整个团队中共享,但个人(或编程对)不能单方面根据这些理解擅自采取行动。无论团队采用了什么样的决策过程,团队一致通过也好,由领导者下命令决定也好,决策过程都必须具有足够的敏捷性,可以反复纠正。团队必须进行有效的沟通,以便使每个人都共享同一个CORE视图。
通常,即便是CORE DOMAIN模型也会包含太多的细节,以至于它很难表达出整体视图。
我们处理大模型的方法通常是把它分解为足够小的子领域,以便能够掌握它们并把它们放到一些独立的MODULE中。这种简化式的打包风格通常是行之有效的,能够使一个复杂的模型变得易于管理。但有时创建独立的MODULE反而会使子领域之间的交互变得晦涩难懂,甚至变得更复杂。
我们不妨考虑采用横向切割而不是纵向切割的方式。多态性(polymorphism)允许我们忽略抽象类型实例的很多细节变化。如果MODULE之间的大部分交互都可以在多态接口这个层次上表达出来,那么就可以把这些类型重构到一个特定的CORE MODULE中。
把模型中最基本的概念识别出来,并分离到不同的类、抽象类或接口中。设计这个抽象模型,使之能够表达出重要组件之间的大部分交互。把这个完整的抽象模型放到它自己的MODULE中,而专用的、详细的实现类则留在由子领域定义的MODULE中。
精炼并不仅限于从整体上把领域中的一些部分从CORE中分离出来。它也意味着,对子领域(特别是CORE DOMAIN)进行精炼,通过持续重构得到更深层的理解,从而向深层模型和柔性设计推进。精炼的目标是把模型设计得更明显,使我们可以用
模型简单地把领域表示出来。深层模型把领域中最本质的方面精炼成一些简单的元素,使我们可以把这些元素组合起来解决应用程序中的重要问题。
当你遇到一个杂乱无章的大型系统时,应该从哪里入手呢?
应首先集中精力把CORE DOMAIN更好地提取出来,完善对CORE的分离,并且把支持性的子领域提炼成通用子领域。
大道至简,复杂系统中最核心最有价值的部分即Core Domian,重点描述了提炼Core Domian的几项措施,分别是:1)HIGHLIGHTED CORE(突出核心),通过标注或者短篇文档说明,来识别出复杂系统内的Core Domian。2)DOMAIN VISION STATEMENT,建立一个核心领域模型的愿景,描述其核心模型的业务价值,使其团队内所有人在高维上达成统一。3)在Core Domain的基础上提炼出通用子域,减少core domian的职责。4)对于Core Domain中的一些复杂算法或者公式,可以通过内聚机制提炼到单独的框架。5)通过在重构的过程中不断分离出Core Domain,因为Core Domain是不断变化的。6)可以采用抽象模式在代码层面对Core Domain进行设计。