DDD领域驱动设计

学习记录,本文来自 https://zhuanlan.zhihu.com/p/3429661476

通用语言

一种能够以简单、明快且精准无误的方式去阐述业务内涵与规则的语言,这,便是通用语言。让领域专家与开发人员得以并肩携手,顺畅地协同合作,进而保障业务需求得以原汁原味、精准无误地呈现出来。DDD 分析和设计过程中的每一个环节都需要保证限界上下文内术语的统一,在代码模型设计的时候要建立领域对象和代码对象的一一映射。

限界上下文

限界上下文其核心要义便是精准锚定语义所处的领域疆界。
限界:直白来讲就是划分出明确的领域边际,宛如一道清晰的界线,将相关范畴与外界隔离开
上下文:营造出的语义环境,为各类概念和表达赋予确切的背景支撑

处于这个特定领域之内的专业术语、业务关键对象等通用语言元素,都被赋予了独一无二、确凿无疑的含义,彻底杜绝了模棱两可的情况出现,这个精心界定的边界还清晰勾勒出模型的适用范畴,让项目团队中的每一位成员都能一目了然:哪些内容应当在模型构建中落地实现,哪些又该被排除在外。

限界上下文和微服务的关系

每一个子域的领域模型都会对应一个限界上下文,而整个领域的领域模型则是由各个限界上下文的领域模型组合而成。理论砂锅来说,限界上下文就是微服务的边界。限界上下文实际上是微服务设计和拆分的核心依据。在领域模型的构建中,若不考虑技术异构、团队沟通等外部因素,理论上每个限界上下文都可以独立设计为一个微服务。

实体

实体是领域模型中的一个对象,带有业务含义的对象,集多个业务属性,业务行为于一体。最大的特点是拥有唯一标识符,这个标识符号贯穿整个软件的生命周期。不随业务的流程和状态变更后变更。在领域模型中以领域对象DO的形式存在。

  • 贫血模型是指领域对象里只有get和set方法(POJO),所有的业务逻辑都不包含在内而是放在Business Logic层。

  • 充血模型是指数据和对应的业务逻辑被封装到同一个类中。因此,这种充血模型满足面向对象的封装特性,是典型的面向对象编程风格。

值对象

指对象就是一个属性集合,将不同的关联属性组合成了一个概念整体,具体整体概念和不可修改的特性

聚合

聚合由业务和逻辑紧密关联的实体和值对象组合而成,是数据修改和持久化的基本单元。

聚合有聚合根和上下文边界,这个边界依据业务单一职责和高内聚原则,界定了聚合内部包含的实体和值对象。而且,聚合之间的边界是松耦合的。

在DDD的分层架构中,聚合属于领域层,领域层包含多个聚合,共同实现核心业务逻辑,聚合内的实体采用充血模型,实现个体业务能力和业务逻辑的高内聚。

聚合根

聚合根的主要作用,是防止复杂数据模型因为缺乏统一业务规则的管控,而出现聚合、实体之间数据不一致的情况。在传统数据模型里,每一个实体地位平等,若任由实体随意调用和修复数据,极有可能造成实体间数据逻辑的混乱,要么是采用锁的方式来解决,又会增加软件复杂度,降低系统性能。
如果把聚合看作一个组织,那么聚合根就相当于这个组织的负责人,也被称为根实体,它即是实体,又承担聚合管理者的角色。
在聚合之间,聚合根是聚合对外的接口。接收外部任务和请求,并在上下文范围内是下聚合之间的业务协作。外部对象若要让问其他聚合实体,不能直接进行访问,而是要先访问聚合根,在通过聚合根导航到聚合内部的实体。

领域事件——解耦微服务的关键

领域事件驱动设计能够切断领域模型之间的强依赖关系。事件发布完成后,发布方无需关注后续订阅方事件处理是否成功,如此便能实现领域模型的解耦,维护领域模型的独立性和数据的一致性。当领域模型映射到微服务系统架构时,领域事件可以解耦微服务,微服务之间的数据无需强一致性,而是基于事件的最终一致性。

DDD分层

传统企业应用大多是单体架构,而单体架构大多是三层架构,三层架构解决了程序内代码间调用复杂、代码职责不清的问题,但是这么分层是逻辑概念,在物理上是中心化的集中式架构,并不适合分布式微服务架构。

DDD分层架构中的要素其实和三层架构类似,只是在DDD分层架构中,这些要素被重新归类,重新划分了层,确定了层与层之间的交互规则和职责边界

演进的核心区域

从三层架构向DDD分层架构的演进,主要集中在业务逻辑层和数据访问层

用户接口层的变化

DDD 分层架构在用户接口层引入了DTO(数据传输对象),为前端提供了更多的数据,并提升了展示的灵活性。

业务逻辑层的优化

DDD 分层架构对三层架构的业务逻辑进行了更清晰的划分,解决了三层架构中,核心业务逻辑混乱,业务代码改动影响较大的问题,具体来说:

  • 应用层:快速相应前端的变化,负责服务的组合、编排和转发
  • 领域层:实现领域模型的能力,专注于核心业务逻辑的表达

数据访问层的改进

在数据访问层和基础层之间,DDD 分层架构引入了仓储(Repository)设计模式,取代了三层架构中的 DAO 方式。仓储模式通过依赖倒置原则,实现了各层对基础资源的解耦。仓储分为两部分:

仓储接口:位于领域层,定义数据访问的契约。
仓储实现:位于基础层,负责具体的数据库操作。
此外,三层架构中通用的第三方工具包、驱动、Common、Utility、Config 等公共资源类,在 DDD 分层架构中被统一放到了基础层。

演进的意义

传统三层架构向ddd分层架构的演进,体现了领域驱动设计思想的逐步成熟和应用,这种演进不仅优化了架构的分层设计,还提高了系统的灵活性和可扩展性。

DDD 的分层架构

  • 用户接口层

主要职责是向用户展示信息并处理用户的指令。这里的“用户” 不仅仅限于人类用户,还包括程序、自动化测试脚本以及批处理脚本等。

  • 应用层
    应用层是一个相对较薄的层次,理论上不应包含具体的业务规则或逻辑,而是专注于用例和流程相关的操作。它位于领域层之上,负责协调多个聚合的服务和领域对象,完成服务的编排和组合,从而执行业务操作。此外,应用层也是微服务之间交互的通道,能够调用其他微服务的应用服务,实现跨微服务的服务组合和编排。
    领域层的职责包括:
    1、服务的组合、编排和转发;
    2、处理业务用例的执行顺序以及结果的组装;
    3、通过 API 网关向前端发布粗粒度的服务;
    4、执行安全认证、权限校验、事务控制;
    5、发送或订阅领域事件等。

  • 领域层
    领域层是实现企业核心业务逻辑的关键层次,通过各种校验手段确保业务的正确性,它主要体现领域模型的业务能力,用于表达业务概念、业务状态、业务规则。领域层包含聚合根、实体、值对象、领域服务等领域模型中的核心对象。

    实体和领域服务是领域层实现业务逻辑的主要组成部分。实体层通常采用充血模型,实现与其相关的所有业务功能。
    当某些业务功能无法由单一实体(或值对象)实现时,领域服务会介入,组合聚合内的多个实体,完成复杂的业务逻辑。

  • 基础层
    第三方工具和驱动
    消息中间件
    API 网关
    文件存储
    缓存服务
    数据库等

== DDD封层架构有一个重要原则:每层只能和位于其下方的层发生耦合 ==

领域模型中对象的层次从内到外依次为:值对象、实体、聚合和限界上下文。

领域模型的推动和微服务架构的演进

  • 聚合的重组或拆分
    聚合可以作为一个整体,在不同微服务模型之间进行重组或拆分,这种调整能够更好的适应业务需求的变化。

  • 聚合独立为微服务
    在某种情况下,可以直接讲一个聚合独立成一个微服务,这种方式可以进一步提升系统的灵活性和可维护性。

posted @ 2025-05-27 18:06  wsl-hitsz  阅读(17)  评论(0)    收藏  举报