03.领域驱动设计

领域驱动设计

领域驱动设计

DDD 领域驱动设计,起源于 2004 年著名建模专家 Eric Evans 发表的他最具影响力的著名书籍:《Domain-Driven Design – Tackling Complexity in the Heart of Software》,书中反复强调领域通用语言(Ubiquitous Language)的重要性,全面阐述了 DDD 战略设计到战术设计的方法论和实践。但是 Eric Evans 在该书中只是提供了一套原始理论,并没有提供一套方法论,因此多年来对于 DDD 也是见仁见智。

软件开发过程很复杂,当我们遇到问题时,我们通常会尝试通过将其变为更易理解和易于管理的部分来解决复杂问题。如今 DDD 已经发展成为了一种针对大型复杂系统的领域建模与分析方法。它完全改变了传统软件开发工程师面向数据库进行的建模方法,从而将要解决的业务概念和业务规则转换为软件系统中的类型以及类型的属性与行为,通过合理运用面向对象的封装、继承和多态等设计要素,降低或隐藏整个系统的业务复杂性,并使得系统具有更好的扩展性,应对纷繁多变的现实业务问题。

领域驱动设计架构

领域驱动设计为软件开发领域提出的一套系统与理论分析方法,它建立了以领域为核心驱动力的设计体系;当导我们面对客户的业务需求,由领域专家与开发团队展开充分的交流,经过需求分析与知识提炼,获得清晰的问题域。然后再引入限界上下文和上下文映射对问题域进行合理的分解,识别出核心领域与子领域,并确定领域的边界以及它们之间的关系;从而把一个大的复杂系统问题拆分成多个细粒度、独立和内聚的业务子问题,从而很好地分解和控制业务复杂度,各个小组聚焦各自的子领域中。DDD 不是一个框架,更非单纯的技术解决方案,绝不是引入某个包就可以实现的。DDD 保持了极大的开放性。例如,可以使用用例(Use Case)、测试驱动开发(TDD)、用户故事(User Story)来帮助我们对领域建立模型;可以引入整洁架构思想及六边形架构,以帮助我们建立一个层次分明、结构清晰的系统架构,界定领域与技术基础设施的边界;引入 CQRS 模式则分离了查询场景和命令场景,针对不同场景选择使用同步或异步操作,提高架构的低延迟性与高并发能力。还可以引入函数式编程思想,利用纯函数与抽象代数结构的不变性以及函数的组合性来表达领域模型。

当然,DDD 的实践并非一蹴而就,往往都会先是套概念,在代码中使用 Aggregation Root,Bonded Context,Repository 等等这些概念;也会使用一定的分层策略,然而这种做法一般对复杂度的治理并没有多大作用。在经过大量的实践之后,就可以融会贯通,理解 DDD 的本质是统一语言、边界划分和面向对象分析的方法。DDD 并非银弹,我们实践 DDD 的根本目的也是为了更快、更好地满足业务不断迭代的需求,并且能够保证团队的延续性与表述一致性,譬如对于问题域中相同变量、指标的定义是一致的。DDD 不适合多数为 CRUD 单表操作的简单业务场景,在该场景下往往导致增加系统复杂度。同样不适合基于老系统代码之上进行的优化重构,因为这样从传统分层模式到基于聚合的设计是完全颠覆性的,论改造成本不如重新开发一套新应用。

领域驱动设计过程