领域驱动设计学习

简介

一个应用系统常常包含许多模块,有基础组件、业务逻辑、数据操作、外部依赖、服务提供等等。但软件系统发展到一定程度时,其复杂性也随之增长,给后期的开发和维护带来难度。

而领域驱动设计则是针对 复杂性 的一个解决手段,使架构能够自我进化。同时由于领域驱动设计强调领域模型的重要性,与微服务思想恰到好处,自然被越来越多的架构设计所采纳。

软件的复杂性,其源头主要是由于对业务需求的抽象设计不足所导致的,按照我在日常开发流程中的接触,认为主要原因是 分工 所导致的认识不全面,开发人员只关注于需求,没有梳理出项目所需的业务知识。

一个完整的领域驱动设计周期需要包括 建立业务领域模型分析领域场景建立统一语言识别限界上下文设计分层架构 这几个阶段。

建模

领域建模是领域驱动设计周期中最重要的一个阶段,一个良好的模型设计能使得系统结构清晰整洁、分层合理,对日后的变化达到可进化性、可扩展性、可定制性。

这个阶段需要先与项目的相关人员都进行沟通,基于对象事件进行分析说明,解决存在困惑,使得成员对业务期望有普遍理解,初步达成领域知识的共识。

  1. 首先,需要对业务建立逻辑模型与物理模型,识别业务需求,将业务逻辑与技术实现进行隔离。

  2. 对业务逻辑进行分治、抽象、封装,做到化繁为简,降低系统的复杂性。

  3. 分析识别问题域,根据需求目标的重要性确定其优先级(主要功能与基础功能先之、外部协作功能次之)

事件风暴 是一个常用且高效的领域事件建模方法。

分析场景

通过分析业务逻辑提炼场景,才能更好的完善领域模型,常用的方式有 用例、用户故事、测试驱动开发,每个方式的关注点也大相径庭。

用例

用例是软件开发中最熟悉的设计方法,它以 领域 为核心,通过梳理整个流程,抽象出业务领域模型。

用户故事

相比与用例的抽象,用户故事则是具体的。它将接收特定的事件并根据一定的条件转化为结果进行输出,强调 业务规则业务流程

测试驱动开发

测试驱动开发的目的在于对职责进行 拆分,模拟现实场景分解任务,保证测试任务的粒度足够细。

四色原型 是对事件分析的手段,也叫 彩色UML。

建立统一语言

统一语言是领域驱动设计之中十分重要的一个环节,其核心价值在于 理解。在进行需求沟通时,为避免不一致的理解所产生的认识障碍,需要建立出团队中各个成员都理解的的术语进行交流,这一过程就是建立统一语言。

统一语言体现在两个方面:统一的领域术语、领域行为描述

统一的领域术语

领域术语的设立目的是为了规避那些表达含义混淆的术语,提高沟通和交流的效率。

正确的术语建立需要业务人员通过对模型需求进行分析,提炼出概念一致的中英文语言及解释,甚至提供详细的案例说明来确保能够做到表达明确,并通过 术语表 进行维护。

领域行为描述

领域行为描述是对业务过程的详细解释,遵守且延伸于领域术语,侧重于体现完整的业务需求以及复杂的业务规则。

根据领域行为描述中的前置条件、业务规则、流程状态、执行结果,并且直接融入编码实现,使得代码逻辑清晰可读,自身就能对领域行为进行描述。

限界上下文

限界上下文的含义是保证目标业务流程不受外部因素干扰,即项目的系统架构与组织结构都是可控的。要正确理解限界上下文,就需要对 上下文边界 有清晰的认识。

上下文

上下文划分的价值主要体现在三个方面,领域逻辑层面、团队合作层面、技术实现层面。

  • 领域逻辑层面 限界上下文确定了领域模型的业务边界,维护了模型的完整性与一致性,从而降低系统的业务复杂度。

  • 团队合作层面 限界上下文确定了开发团队的工作边界,建立了团队之间的合作模式,避免团队之间的沟通变得混乱,从而降低系统的管理复杂度。

  • 技术实现层面 限界上下文确定了系统架构的应用边界,保证了系统层和上下文领域层各自的一致性,建立了上下文之间的集成方式,从而降低系统的技术复杂度。

边界

边界的职责是确定限界上下文的 控制力,体现了高内聚低耦合的思想,主要包括以下几个要素。

  • 最小完备 要求限界上下文的控制权在其自身,无需依赖其他上下文的信息,整个业务流程是安全的。

  • 自我履行 自我履行是指对外部的请求能够很好的判断该请求是否属性当前上下文的职责范围内,还是应该交付给其他上下文。

  • 稳定空间 稳定空间就是要对限界上下文拥有掌控权,对外部交互以接口的形式进行抽象。

  • 独立进化 指的是当限界上下文发生变化时,不会对外界造成影响,意在服务演化中的兼容性。

分层架构

软件设计中的分层架构已经成为了开发人员心中的规范了,领域驱动设计也有一套分层的依据与原则。

分层的方式一般是对系统整体进行水平切分,目的在于打造出抽象层次不同的架构,将业务与技术分离开。

根据关注点可分为面向用户、面向应用、面向业务、面向资源,业务相关性由低至高。

  • 根据业务特性,设计适当的分层架构。例如 六边形架构、洋葱圈架构、事件驱动模型、函数式编程、QCRS模式 等。

面向资源

该层为基础设施层,主要提供了具体的外部资源获取方式,可能有数据库、文件系统、远程通信,属于最稳定的一组服务。

面向业务

该层为业务流程的拆分,将职责的抽象与实现剥离,提供抽象的接口,隐藏内部的实现。

面向应用

该层为业务流程的合成,根据业务规则将抽象接口进行组装,通过依赖注入实现接口,提供完整的业务功能。

面向用户

该层的职责主要提供了外部进程访问领域资源的手段,这里的用户可以是前端接口、远程通信服务。

基于个人理解的六边形架构的 maven archetype 实现

https://www.jdon.com/ddd.html https://www.jianshu.com/p/b6ec06d6b594 https://tech.meituan.com/DDD%20in%20practice.html