子领域的边界明确了问题空间中领域的优先级,限界上下文的边界则确保了领域建模的最大*度。这也是战略设计在分治上起到的效用。当我们在战略层次从问题空间映射到解空间时,子领域也将映射到限界上下文,即可根据子领域的类型为限界上下文选择不同的建模方式。例如为处于核心子领域的限界上下文选择领域模型(domainmodel)模式,为处于支撑子领域(supporting subdomain)的限界上下文选择事务脚本(transactionscript)模式,这样就可以灵活地平衡开发成本与开发质量。
战术设计阶段需要在限界上下文内部开展领域建模,前提是你为限界上下文选择了领域模型模式。在限界上下文内部,需要通过分层架构将领域独立出来,在排除技术实现的干扰下,通过与领域专家的协作在统一语言的指导下逐步获得领域模型。战术设计阶段最重要的设计元模型是聚合模式。虽然聚合是实体和值对象的概念边界,然而在获得了清晰表达领域知识的领域模型后,我们可以将聚合视为表达领域逻辑的最小设计单元。如果领域行为是无状态的,或者需要多个聚合的协作,又或者需要访问外部资源,则应该将它分配给领域服务。
至于领域事件,则主要用于表达领域对象状态的迁移,也可以通过事件来实现聚合乃至限界上下文之间的状态通知。战略设计与战术设计并非割裂的两个阶段,而是模型驱动设计过程在不同阶段展现出来的不同视图。战略设计指导着战术设计,这就等同于设计原则指导着设计决策。EricEvans就明确指出,“战略设计原则必须把模型的重点放在捕获系统的概念核心,也就是系统的‘远景’上。”当一个业务系统的规模变得越来越庞大时,战略设计高屋建瓴地通过限界上下文规划了整个系统的架构。只要维护好限界上下文的边界,管理好限界上下文之间的协作关系,限制在该边界内开展的战术设计所要面对的就是一个复杂度得到大幅降低的小型业务系统。人们常以“只见树木,不见森林”来形容一个人不具备高瞻远瞩的战略眼光,然而,若是“只见森林,不见树木”,也未见得是一个褒扬的好词语,它往往可以形容一个人好高骛远,不愿意脚踏实地将战略方案彻底落地。
无论战略的规划多么完美,到了战术设计的实际执行阶段,团队在开展对领域的深层次理解时,总会发现之前被遗漏的领域概念,并经过不断的沟通与协作,“碰撞”出对领域的新的理解。对领域概念的新发现与完善除了能帮助我们将领域模型突破到深层模型,还可能促进我们提出对战略设计的修改与调整,其中就包括对限界上下文边界的调整,从而使战略设计与战术设计保持统一。从战略设计到战术设计是一个自顶向下的设计过程,体现为设计原则对设计决策的指导;将战术设计方案反馈给战略设计,则是自底向上的演化过程,体现为对领域概念的重构引起对战略架构的重构。二者形成不断演化、螺旋上升的设计循环。
领域模型驱动设计
领域驱动设计是一种思维方式[8]2,而模型驱动设计则是领域驱动设计的一种设计元模型。因此,模型驱动设计必须在领域驱动设计思维方式的指导下进行,那就是面向领域的模型驱动设计,或者更加准确地将其描述为领域模型驱动设计。领域模型驱动设计通过单一的领域模型同时满足分析建模、设计建模和实现建模的需要,从而将分析、设计和编码实现糅合在一个整体阶段中,避免彼此的分离造成知识传递带来的知识流失和偏差。它树立了一种关键意识,就是开发团队在针对领域逻辑进行分析、设计和编码实现时,都在进行领域建模,产生的输出无论是文档、设计图还是代码,都是组成领域模型的一部分。EricEvans将那些参与模型驱动设计过程并进行领域建模的人员称为“亲身实践的建模者”(hands-on modeler)。
模型驱动设计主要在战术阶段进行,换言之,整个领域建模的工作是在限界上下文的边界约束下进行的,统一语言的知识语境会对领域模型产生影响,至少,建模人员不用考虑在整个系统范围下领域概念是否存在冲突,是否带来歧义。由于限界上下文拥有自己的内部架构,一旦领域模型牵涉到跨限界上下文之间的协作,就需要遵循限界上下文与上下文映射的架构约束了。
既然模型驱动设计是面向领域的,就必须明确以下两个关键原则。
-
以领域为建模驱动力:在建模过程中,针对领域知识提炼抽象的领域模型,并不断针对领域模型进行深化与突破,直到最终以代码来表达领域模型。
-
排除技术因素的干扰:领域建模与技术实现的关注点分离有助于保证领域模型的纯粹性,也能避免混淆领域概念和其他只与技术相关的概念。
模型驱动设计不能一蹴而就。毕竟,即使通过限界上下文降低了业务复杂度,对领域知识的理解是一个渐进的过程。在这个过程中,开发团队需要和领域专家紧密协作,共同研究领域知识。
在获得领域模型之后,也要及时验证,确认领域模型有没有真实表达领域知识。一旦发现遗漏或失真的现象,就需要重构领域模型。首先建立领域模型,然后重构领域模型,进而精炼领域模型,保证领域概念被直观而真实地表达为简单清晰的领域模型。显然,在战术设计阶段,模型驱动设计也应该是一个演进的不断完善的螺旋上升的循环过程。
本文摘录于张逸老师新书《解构领域驱动设计》。