
概述

DDD,领域驱动设计(Domain Driven Design),是由Eric Evans最早提出的综合软件系统分析和设计的面向对象建模方法,如今已经发展为一种针对大型复杂系统的领域建模与分析方法。也就是说DDD适用于可预见的即将向复杂业务系统发展的简单业务系统,或需要进行重构的大型复杂业务系统。
DDD的设计过程分为战略设计阶段和战术设计阶段(就像大多数设计过程一样,总有一个从抽象到具体、从整体到局部的过程),在设计过程中会涉及几个主要的概念,如:问题域、事件风暴、限界上下文、上下文映射、聚合根、六边形架构、事件驱动架构、CQRS模式、贫血模型与充血模型等。这些概念将会在领域驱动设计的不同阶段发挥各自的作用,下面做个详细的解释。

战略设计

领域驱动设计的战略设计阶段是从两个方面来考量的:问题域方面和架构方面。

问题域方面

问题域方面的设计不包含任何的技术方案和实现细节,其主要思路是,列出所有的业务域(即业务对象),然后对列出的业务域根据其实际关系进行分类聚合。进行问题域设计的一个主要方法是事件风暴,遵守的一个原则是实事求是,即现实世界有什么事物就有什么对象、现实世界有什么行为就有什么方法、现实世界有什么关系就有什么关联。
事件风暴的操作方法为,罗列出业务场景中的所有事件,如订单交易场景中的登录、浏览、下单、支付、评价等事件,然后以事件为中心,绘制出与该事件相关的所有对象及其属性与行为(可用类图展示),最后再对这些对象进行聚合分类。
通过事件风暴划分和聚合出来的业务域即限界上下文,每一个限界上下文都可以作为一个微服务进行独立开发和部署。每一个限界上下文中的核心对象就叫做聚合根,如用户信息、用户地址信息等聚合成的用户管理域中的聚合根即为用户信息。
问题域设计的主要目的是将业务域进行聚合分类,从业务角度将关联性强的对象进行聚合,将关联性不强的对象进行分类。不同限界上下文之间的通信叫做上下文映射。

架构方面

上文已经讲述了如何进行限界上下文的划分,不过划分好之后又如何进行架构设计呢?以下四种通用架构模式可以组合使用。
分层架构
通过分层架构来隔离关注点,尤其是将领域独立出来,可以更利于领域模型的单一性与稳定性。分层架构的最好设计模式为整洁架构设计模式,如下图所示。

在Bob大叔的整洁架构中,实体与用例(领域层)与业务逻辑相关,框架与驱动(基础设施层)与技术实现相关,中间通过适配器进行隔离。这样当业务需求变动时只需要关注领域层,技术更新或替换时只需要关注基础设施层即可。
六边形架构
六边形架构以“内外分离”的方式,更加清晰地勾勒出业务逻辑与技术实现的边界,且将业务逻辑放在了架构的核心位置。

体现业务逻辑的应用层与领域层处于六边形架构的内核,并通过内部的六边形边界与基础设置的模块隔离开。当我们在进行软件开发时,只有恪守架构上的六边形边界,就不会让技术实现的复杂度污染业务逻辑,保证了领域的整洁。边界还隔离了变化产生的影响。如果我们在领域层或应用层抽象了技术实现的接口,再通过依赖注入将控制的方向倒转,业务内核就会变得更加稳定,不会因为技术选型或其他决策的变化而导致领域代码的修改。
事件驱动架构
倘若在架构设计时,皆以事件为媒介驱动架构的设计,并利用事件来解耦两个协作者之间的协作时,就可以认为是事件驱动架构。如果限界上下文之间采用事件进行协作,则采用的上下文映射模式就是发布者/订阅者模式。
典型的事件驱动架构就是网络I/O中的Reactor模式,如下图所示。

在Reactor模式中,每个网络请求都是一个事件,由同步事件分离器来接收网络请求,并将其交给事件发布器(Dispatcher)进行事件分发,最终交给线程池进行异步事件处理。
CQRS架构
因命令与查询操作有着诸多差异,所以在架构设计上需要分别对待它们,给出完全不同的架构设计方案。

在CQRS中,命令是系统中引起状态变化的活动,通过是一种命令语气;事件则描述了某件事情的发生,通常是命令的结果。如上图,当一个命令下发时,通过命令处理器,聚合成对不同与模型的处理,在存入数据库的同时,通过事件总线同步到事件查询库,供事件查询处理器调用。

战术设计










