领域驱动设计

领域驱动设计(Domain Driven Design)的概念出现于 2003 年,与敏捷相比,DDD 在提出之后的很多年都没有称得上“流行”,甚至说从未真正流行过。一部分是因为 DDD 涉及了一些新的名词和概念(比如聚合、限界上下文和领域等),在缺乏具体实践案例的场景下,较难理解这些抽象概念,这导致了学习和应用 DDD 的初期阶段就变得不太顺畅,开发人员可能并不能领会到其中的设计思想及其带来的价值。但是在小范围群体内,逐渐有一批工程师开始能够掌控这种建模方法,并使用 DDD 来设计出具有较高业务复杂性的软件应用。

2013年后,分布式的基础设施逐渐成熟。Martin Fowler 于 2014 年发表了系统阐述微服务的文章,微服务架构开始兴起。软件工程师们发现将单体应用采用微服务架构进行划分需要大量的实践经验和理论基础作指导,否则不能完全体现微服务架构所带来的优势。不过早期熟悉 DDD 思想的开发者发现,DDD 可以有效地根据业务对复杂软件系统进行拆解,微服务架构与 DDD 相得益彰。按照软件工程的思想,我们在创建微服务时,需要满足高内聚、低耦合的要求。而根据 DDD 的思想,可以将限界上下文与微服务进程对应起来。DDD 中限界上下文的概念很契合匹配微服务要求,这两者都强调从业务角度进行划分,以应对日益复杂的软件系统。由此,DDD 迎来了它的高速发展和推广时期。

DDD 不是语言,不是框架,不是架构,而是一种思想,一种方法论,它可以分离业务复杂度和技术复杂度;DDD 也并不是一个新的事物,它是面向对象的提升,最终目标还是高内聚、低耦合

Eric Evans在《领域驱动设计》一书中,提出了经典的四层架构,如下图所示:

DDD领域分层

  • 用户界面User Interface
    负责给用户展示信息,并解释用户命令。
  • 应用层Application
    负责协调应用程序的活动。不包括任何业务逻辑,不保存业务对象的状态,但能保存应用程序任务过程的状态。
  • 领域层Domain
    负责业务领域的信息和状态的保存和维护。业务对象的持久化和它们的状态可能会委托给基础设施层。
  • 基础设施层Infrastructure
    负责支持其他层次,提供基础的消息传递、数据持久化等功能。它提供层之间的信息传递,实现业务对象的持久化,包含对用户界面层的支持性库等。

我们以购物车下订单功能为例来解释这各个层面的作用:

  • 用户界面层提供下单的接口
  • 应用层负责逻辑的整合,如购物车清空、检查库存等
  • 领域层将购物车相关的业务逻辑封装到一个 ShoppingCar 对象中,调用 shoppingCar.order下订单,业务服务的重心从生成订单表中的记录转移到购物车对象本身
  • 底层数据库中如何生成这条记录并不属于我们的核心业务逻辑,这对应 DDD 中的基础设施层,由 Repository 或者 Dao 等数据交互对象负责去持久化我们对领域模型下达的指令所产生的数据库变化。