《解构领域驱动设计》篇首语

《解构领域驱动设计》在领域驱动设计统一过程的指导下,将该过程的全部三个阶段作为本书的三个核心篇章:全局分析、架构映射与领域建模,再辅以开篇和融合,共分为五篇二十五章,全面而完整地表达了我对领域驱动设计的全部认知与最佳实践。

开篇

开篇,明义。
领域驱动设计需要应对软件复杂度的挑战!那么,软件复杂度的成因究竟是什么?又该如何应对?概括而言,即:

  • 规模:通过分而治之控制规模
  • 结构:通过边界保证清晰有序
  • 变化:顺应变化方向

领域驱动设计对软件复杂度的应对之道可进一步阐述为:

  • 规模:以子领域、限界上下文分而治之
  • 结构:以分层架构隔离业务复杂度与技术复杂度,形成清晰的架构
  • 变化:通过领域建模抽象为以聚合为核心的领域模型,响应需求之变化

子领域、限界上下文、分层架构与聚合皆为领域驱动设计的核心元模型,分属战略设计和战术设计,贯穿了从问题空间到解空间的全过程。

领域驱动设计的开放性是其生命长青的基石,但它过于开放的灵活性也让运用领域驱动设计的开发团队变得举步维艰。我之所以提出领域驱动设计统一过程,正是要在开放的方法体系指导之下,摸索出一条行之有效的软件构建之路。它既不悖于领域驱动设计之精神,又不吝于运用设计元模型,通过提供简单有效的实践方法,建立具有目的性和操作性的构建过程。

领域驱动设计统一过程分为三个阶段:

  • 全局分析阶段
  • 架构映射阶段
  • 领域建模阶段

每个阶段的过程工作流既融合了领域驱动设计既有的设计元模型,又提出了新的模式、方法与实践,丰富了领域驱动设计的外延。领域驱动设计统一过程对项目管理、需求管理与团队管理也提出了明确的要求,它们虽然不属于领域驱动设计关注的范畴,却是影响领域驱动设计实践与落地成功与否的重要因素。
领域驱动设计统一过程是对领域驱动设计进行解构的核心内容!

全局分析

解决问题的第一要务是明确问题,问题尚不知,就尝试求解,自然就是无的放矢了。全局分析的目标就是确定问题空间,在统一语言的指导下,通过各种可视化手段,由领域专家与团队一起完成对问题空间的探索,帮助领域驱动设计对准问题,输出价值需求和业务需求。

价值需求既是目标系统的目标,也是对目标系统问题空间的界定和约束,它指导着业务需求分析。业务需求由动态的业务流程和静态的业务活动组成,二者的结合依靠业务场景按照时间点和业务目标对业务流程的切分。通过运用商业模式画布,可以获得组成价值需求的利益相关者、系统愿景和系统范围。

业务流程的梳理可以帮助团队对问题空间的各条业务线构成一个整体认识,弄清楚各种角色如何参与到一个完整的流程中,流程的时序性也可以避免识别业务活动时可能出现的缺失。业务流程图与服务蓝图以可视化的方式形象地呈现每一个提供了业务价值的业务流程。

业务活动是角色与目标系统之间的一次功能性交互,是体现了服务价值的功能行为。一直以来,该如何确定业务需求层次,划分业务需求粒度,总是众说纷纭,没有一个客观的标准;业务活动将目标系统视为一个黑盒子,从功能性交互的完整性保证了每个业务活动都是正交的,就无需再考虑业务活动的层次和粒度,或者说,只要确定了完整性,保障了正交性,业务活动的层次与粒度也就确定下来了。业务活动可以使用用例、用户故事或事件风暴中的事件来表达。

业务活动是全局分析阶段的基本业务单元,它的输出对于架构映射与领域建模具有重要意义:

  • 架构映射:业务活动是识别限界上下文、确定上下文映射的基础,同时,它的粒度正好对应每个限界上下文向外公开的服务契约;
  • 领域模型:业务需求分析细化的业务活动既是领域分析建模的重要参考,同时又作为服务场景成为场景驱动设计的起点。

全局分析是领域驱动设计统一过程的起点,它的目的是探索问题空间,使团队就问题空间的价值需求和业务需求达成共识,并在统一语言的指导下将其清晰地呈现出来。只有问题定义清楚了,团队才能更好地寻求解决方案。

架构映射

架构映射对应解空间的战略设计层次。

本阶段,映射成为了获得架构的主要设计手段。价值需求中利益相关者、系统愿景和系统范围可映射为系统上下文,业务活动通过对业务相关性的归类与归纳可映射为限界上下文,二者又是构成系统架构的重要层次,前者勾勒出解空间的控制边界,后者勾勒出领域模型的知识边界,组成了一个稳定而又具有演进能力的领域驱动架构。
限界上下文是架构映射阶段的基本架构单元,决定一个限界上下文边界的元素包括:领域对象、领域知识、角色和活动。限界上下文是领域模型的知识语境,又是业务能力的纵向切分,它满足自治单元的四个要素:最小完备、自我履行、稳定空间、独立进化。一个自治的限界上下文一定遵循菱形对称架构模式。

菱形对称架构模式将整个限界上下文分为内部的领域层和外部的网关层,网关层根据调用方向分为北向网关和南向网关。北向网关体现了“封装”的设计思想,根据通信方式的不同分为远程服务与应用服务;南向网关体现了“抽象”的设计思想,将抽象与实现分离,分为端口与适配器。在诸多上下文映射模式中,除了共享内核与遵奉者模式,都应在菱形对称架构网关层的控制下进行协作。

系统上下文对应了解空间的范围,它站在组织层面思考利益相关者、目标系统与伴生系统之间的关系。它通过系统分层架构体现目标系统的逻辑结构,并按照子领域价值的不同,为限界上下文确定了不同的层次。根据康威定律的规定,系统分层架构可以映射为由前端组件团队、领域特性团队与组件团队组成的开发团队。

限界上下文是顺应业务变化进行功能分解的软件元素,菱形对称架构规定了限界上下文之间、限界上下文与外部环境之间的关系,由系统分层架构模式与菱形对称架构模式组成的领域驱动架构风格则是指导架构设计与演进的原则。这些内容符合架构的定义,同时也是对控制软件复杂度的呼应。

领域建模要在架构的约束下进行,系统上下文和限界上下文的边界对领域模型起到了设计约束的作用。根据限界上下文的价值高低,属于支撑子领域和通用子领域的限界上下文,往往因为业务简单,无需进行领域建模,如此就能快速开发,降低开发成本。因此,架构映射是领域建模的前提,也可以认为是战略对战术的设计指导。

领域建模

领域建模的过程,是模型驱动设计的过程,也是迭代建模的过程。

不可妄求一蹴而就能获得完整的领域模型,也不可殚精竭虑地追求领域模型的尽善尽美。领域建模的分析、设计和实现是循序渐进的增量建模,建模目标与侧重点也不尽相同。

领域分析模型负责捕捉表示领域知识的领域概念,明确它们之间的关系,形成反映现实世界的对象概念图。获得的分析模型全面而粗疏,既不至于遗漏重要的领域概念导致模型的缺失,又不至于锱铢必较地因为过分定义领域属性而陷入分析瘫痪。

领域设计模型在领域分析模型的基础上加入对设计和实现的思考,为对象概念图戴上聚合的镣铐,在保证概念完整性、独立性、不变量与一致性的基础上,更好地管理对象的生命周期。场景驱动设计则赋予了领域模型以动能,在对服务场景进行任务分解的基础上,由外自内由各种角色构造型参与协作,形成了连续执行的消息链条,驱动出远程服务、应用服务、领域服务、聚合和各种端口的方法,既验证了领域模型对象的正确性与完整性,又丰富了领域模型的内容。

领域实现模型基于场景驱动设计输出的任务列表和序列图脚本开展测试驱动开发,领域层的产品代码与测试代码共同构成领域实现模型。由于拥有单元测试的保护,及时重构又改进了代码的质量,使得领域实现模型变得整洁而稳定,形成具有运行能力的核心领域资产。在实现领域模型时,也是对领域设计模型和领域分析模型的一次验证。

聚合是领域建模阶段的基本设计单元。领域分析模型向领域设计模型的演进是通过识别聚合完成的,聚合边界的约束能力使得领域设计模型在保证细粒度对象定义的同时,又能通过封装实体与值对象的细节简化对象模型,降低领域模型的复杂度。一旦确定了聚合,就可以由此定义资源库端口和领域服务,并按照信息专家模式将体现领域逻辑的原子任务分配给聚合,建立富领域模型。聚合是纯粹的,它不依赖于任何访问外部资源的端口,因此它也是稳定的;因为聚合是稳定的,使得围绕着它为核心建立的领域模型也变得更加稳定。

融合

融合,就是战略和战术的融合,为了让软件运行起来,还需考虑领域逻辑与技术实现的融合,即领域层与网关层的融合。

在战略层次,需在领域驱动架构风格的约束和指导下考虑限界上下文之间的协作,思考并决策限界上下文的通信边界,思考从单体架构向微服务架构的演进,同时,因为进程间通信引起的诸多影响,需评估分布式通信、事务以及受技术因素驱动的命令查询职责分离模式是否对领域模型造成了影响。

事实证明,遵循领域驱动架构风格的系统完全满足架构演进的要求,只需付出少量修改成本,即可支持单体架构、SOA架构、微服务架构与事件驱动架构,同时还满足了领域模型的稳定性。

在战术层次,通过建立设计概念的统一语言,保证团队在领域建模时避免因概念理解的偏差出现设计的不一致,甚至做出有违领域驱动设计理念的错误决策。通过领域模型驱动设计获得的领域模型还需要考虑如何与持久化结合,解决对象关系映射的阻抗不匹配问题,以更加优雅的方式实现资源库,保证作为端口的资源库实现不会侵入领域模型,破坏领域的纯粹性。

无论战略还是战术,抑或二者的融合,都需要在领域驱动设计知识体系的指导下进行。结合领域驱动设计社区的发展与我个人的设计经验,尝试对领域驱动设计做进一步梳理和升华,建立了全方位多维度的领域驱动设计魔方,基于领域驱动设计统一过程给出了具有可操作性的参考过程模型,提炼了领域驱动设计的精髓,面向团队给出领域驱动设计的能力评估模型,如此就能将方法、过程、模式有机地融合起来,给出行之有效的指导意见。