领域驱动设计(四)战略设计
上一篇我们学习了如何通过重构去发现深层次的模型,并介绍了一些在重构中常用的模式,如:INTENTION-REVEALING INTERFACES、SIDE-EFFECT-FREE FUNCTION、ASSERTION、CONCEPTUAL CONTOUR、STANDALONE CLASS、CLOSURE OPERATION。我们已经学习了构造块和设计模式,可以通过这些模式来帮助我们设计领域模型。那往往一个真实系统的模型复杂性比我们所讲的所有例子都要复杂上百倍千倍,那么在如此复杂的一个模型中,我们要如何把控呢,才能保证自己不迷失,才能保证设计出来的模型是符合领域的,是高效的?接下来我们要说说如何从全局、从整体的角度出发,来进行领域模型设计工作。
正如标题战略设计,战略就是一个大方向,当我们要做一件大事时,首先必须有一个方向,有了方向才知道应该怎么去做,熟知战略会时刻提醒我们不要跑偏。领域模型设计的战略有三个原则:上下文、精炼、大型结构。这三个原则是互为补充,在实际情况中是多种方式进行互动,例如,一种大型结构可以存在于一个BOUNDED CONTEXT中,也可跨越多个BOUNDED CONTEXT存在,并用于组织CONTEXT MAP。
上下文是为了保证模型的完整性和统一性,如下图,一个系统往往会有多个模型,每个模型都有bounded context,而这些bounded context之间的关系便形成了context map。然后我们可以利用一系列的模式来帮助我们实现context map的能力。比如SHARED KERNEL共享内核就是我们常用的,多上下文相同的部分,可以提炼出来共享,从而形式共享内核。
BOUNDED CONTEXT,界限上下文。细胞之所以能够存在,是因为在细胞膜限定了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜。由此可见界限是保证事物清晰有序的关键。明确地定义模型所应用的上下文。根据团队的组织、软件系统的各个部分的用法以及物理表 现(代码和数据库模式等)来设臵模型的边界。在这些边界中严格保持模型的一致性,而不要受 到边界之外问题的干扰和混淆。大型项目上会有多个模型共存,在很多情况下这没什么问题。不同的模型应用于不同的上下文中。例如,你可能必须将你的新软件与一个外部系统集成,而你的团队对这个外部系统没有控制权。在这种情况下,任何人都明白这个外部系统是一种完全不同的上下文,不适用他们正在开发的模型,但还有很多情况是比较含糊和混乱的。那这样两个不同的bounded context,我们通过可以以适配器的方式去实现两个系统的关联,但如何一个系统需要与很多个不同的系统集成呢,每个不同系统的集成写一个适配器?这样我们的管理工作又变了复杂起来,所以这时候往往我们是采用上图中的OPEN HOST SERVICE模式,我们定义一个开放服务协议,对外提供服务。所以关注界限上下文,才能很好的将你的关注点放在模型真正应该解决的问题上。
CONTEXT MAP,上下文地图,在上面的描述中,我们已经明确了context map的具体含义了。context map提供的是一个全局视图,让项目人员清楚多个bounded context之间关联的部分。那CONTEXT MAP的具体形式是什么样子呢?可以是文字描述,可以是非正式的图,但应该具有以下两个重点:
(1) BOUNDED CONTEXT应该有名称,以便可以讨论它们。这些名称应该被添加到团队的UBIQUITOUS LANGUAGE中。
(2) 每个人都应该知道边界在哪里,而且应该能够分辨出任何代码段的CONTEXT,或任何情况的CONTEXT。
有很多种方式可以满足第二项需求,这取决于团队的文化。一旦定义了BOUNDED CONTEXT, 那么把不同上下文的代码隔离到不同的MODULE中就再自然不过了,但这样就产生了一个问题— —如何跟踪哪个MODULE属于哪个CONTEXT。我们可以用命名规范来表明这一点,或者使用其他简单且不会产生混淆的机制。
接下来我们关注下什么是精炼?精炼是发现关注领域中的领域,也就是核心领域。一个严峻的现实是我们不可能对所有设计部分进行同等的精化,而是必须分出优先级。为了使领域模型成为有价值的资产,必须整齐地梳理出模型的真正核心,并完全根据这个核心来创建应用程序的功能。Core Domain是需要深层次理解领域知识,并熟用设计模式来帮助我们实现设计的。
最后,我们来看一下大型结构。无论项目的规模如何,人们总需要有各自的分工,来负责系统的不同部分。如果没有任何协调机制或规则,那么相同问题的各种不同风格和截然不同的解决方案就会混杂在一起,使人们很难理解各个部分是如何组织在一起的,也不可能看到整个系统的统一视图。从设计的一个部分学 到的东西并不适用于这个设计的其他部分,因此项目最后的结果是开发人员成为各自MODULE的专家,一旦脱离了他们自己的小圈子就无法互相帮助。在这种情况下,BOUNDED CONTEXT也使项目变得支离破碎。在一个大的系统中,如果因为缺少一种全局性的原则而使人们无法根据元素在模式(这些模式被应用于整个设计)中的角色来解释这些元素,那么开发人员就会陷入“只见树木,不见森林” 的境地。
“大型结构”是一种语言,人们可以用它来从大局上讨论和理解系统。它用一组高级概念或 规则(或两者兼有)来为整个系统的设计建立一种模式。这种组织原则既能指导设计,又能帮助理解设计。另外,它还能够协调不同人员的工作,因为它提供了共享的整体视图,让人们知道各个部分在整体中的角色。说了这么多概念,举个例子来理解一下,比如我们非常熟悉的分层架构就是一种大型结构,那在我们的项目开发中,我们可以定义职责分层,如下图,是一种非常好用也常用的一种分层,再比如隐喻,如防火墙。
上一篇:
本文中讲述的概念和示例均摘自《领域驱动设计-软件复杂性应对之道》