来源:mikechen的互联网架构

DDD是现在非常火热的,而且大厂面试也经常考察,下面我就全面来详解DDD领域驱动设计

DDD全称是Domain-Driven Design,翻译过来就是领域驱动设计,DDD 架构是一种软件设计方法论。

如下图所示:

DDD架构的作用

DDD架构通过边界划分,将复杂业务领域简单化,帮助我们设计出清晰的领域和应用边界。

以下是领域驱动设计的一些主要作用和好处:

1.更好的业务理解和沟通

DDD 强调通过领域模型来表示业务领域,这有助于团队成员更深入地理解业务规则、需求和概念。

2.模块化和可维护性

DDD 强调在开发中构建清晰的模块,如聚合和实体,这种模块化设计有助于代码的可维护性。

3.更好的架构设计

DDD 提供了一些模式和概念,比如:聚合、限界上下文等,有助于设计出更合适的架构。

4.减少重复劳动

通过创建可重用的领域模型和模块,可以减少开发过程中的重复劳动,这有助于提高开发效率并降低错误率。

DDD分层架构

DDD最有标志性的一点,就是将传统软件设计三层模型转化为了四层模型,这个转化如下图所示:

主要分为如下四层:

1.用户界面层

网络协议的转化/统一鉴权/Session管理/限流配置/前置缓存/异常转换

2.应用层

业务流程编排(仅编排,不能存在业务逻辑)/ DTO出入转化

3.领域层

领域模型/领域服务/仓储和防腐层的接口定义

4.基础设施层

仓储和防腐层接口实现/存储等基础层能力

DDD架构设计

DDD架构的一些核心设计和原则:

1.领域

指业务领域的知识和规则,DDD 关注于将这些领域知识映射到软件模型中,以便更好地理解业务需求。

领域越大,业务的范围也越大,大的领域可以拆分成小的问题域,称之为子域。

根据子域重要性和功能属性划,可以将其分为三类。

  1. **核心域:**决定产品核心竞争力的子域;

  2. **支撑域:**实现核心域目标所需的,但重要程度不如核心域的子域,一般具备强烈的个性化需求;

  3. **通用域:**具有通用功能,可被多个子域使用的的是通用域。

2.限界上下文

限界上下文是在整个系统中定义一致的领域模型的边界,不同的上下文可能有不同的模型和语言,但在各自范围内是一致的。

主要体现在如下几点:

  1. 限界上下文是领域概念的语言边界与业务边界,在这个边界内领域概念的内涵是清晰、无歧义的。

  2. 限界上下文是团队的工作边界,组织边界与限界上下文对齐。

  3. 限界上下文是技术方案的实施边界,在这个边界内,技术方案是独立自治的,业务逻辑不会落入不同技术边界的间隙。

3.模型驱动设计

DDD 强调构建贴近领域模型的软件设计,模型作为核心驱动开发过程,模型用于表达领域概念、业务规则和关系。

模型驱动设计的关键思想是:

  1. 深入理解领域:开发团队需要深入了解业务领域,与领域专家合作,以便捕捉业务中的核心概念、规则和业务流程。

  2. 建立领域模型:基于对领域的理解,团队将业务概念和规则转化为领域模型,这些模型可以是类、对象、关系图等,用于表达领域的核心特性。

  3. 模型驱动设计:开发过程中,团队将领域模型作为设计和实现的主要依据,比如:代码、数据库设计等都基于领域模型进行构建。

  4. 持续迭代和反馈:在开发过程中,团队根据实际情况不断调整和完善领域模型,这包括了与领域专家的持续交流和迭代。

4.聚合

聚合是相关对象的集合,具有内部一致性边界,在 DDD 中,聚合是数据和业务逻辑的组织单元,通过聚合根来管理状态变更。

每一个聚合有一个聚合根实体,设置聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间数据不一致性的问题。

建议的聚合设计原则:

  1. 在一致性边界之内确保不变性:聚合用来封装真正的不变性,而不是简单地将对象组合在一起。

  2. 设计小聚合:如果聚合聚合包含过多的实体,会提高管理实体的复杂性,高频操作下容易并发冲突,降低了系统的性能。

  3. 在边界之外使用最终一致性:不同的聚合之间不要求强一致性,保证最终一致性。

5.实体

实体是拥有唯一标识的对象,具有生命周期和状态,它们用于表示领域中的有关事物。

比如:在校园教务系统中,每个账户是对应着一个学生,根据学号来唯一标识,可以认为是一个实体。

6.值对象

值对象是没有唯一标识的对象,通常用于描述一些属性或特性。

比如:地址信息{“省”: “广东省”,”市”:”深圳市”},通过对象属性值来识别的对象,则可以认为是一个值对象。

7.领域服务

服务是表示领域中的一些操作或功能,不能被清晰地归类为实体或值对象,它们用于处理跨实体的业务逻辑。

举个例子:在一个路线导航的项目中,“路线”可能是其中的一个实体,如果业务中有“推荐路线上相关的美食”这样一个功能。

那我们会想,这个功能应该归给哪个领域对象,给“路线”实体吗?有点不合适,应该路线本身关注的是起终点,时间人物等。

此时可以将其这个功能归为领域服务,它是一个路线状态无关的服务,输入路线各个节点,来得到沿路的各种美食。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024922/viewspace-3008919/,如需转载,请注明出处,否则将追究法律责任。