DDD代码模型!

服务的封装与组合

基础层:

  • 基础层的服务形态主要是仓储服务。
  • 仓储服务包括接口和实现两部分。
  • 仓储接口服务供应用层或者领域层服务调用,仓储实现服务,完成领域对象的持久化或数据初始化。

领域层:

  • 领域层实现核心业务逻辑,负责表达领域模型业务概念、业务状态和业务规则。
  • 主要的服务形态有实体方法和领域服务。
  • 实体采用充血模型,在实体类内部实现实体相关的所有业务逻辑,实现的形式是实体类中的方法。
  • DDD提倡富领域模型,尽量将业务逻辑归属到实体对象上,实在无法归属的部分则设计成领域服务。
  • 领域服务会对多个实体或实体方法进行组装和编排,实现跨多个实体的复杂核心业务逻辑。

应用层:

  • 应用层用来表述应用和用户行为,负责服务的组合、编排和转发,负责处理业务用例的执行顺序以及结果的拼装,负责不同聚合之间的服务和数据协调,负责微服务之间的事件发布和订阅。

  • 应用服务内用于组合和编排的服务,主要来源于领域服务,也可以是外部微服务的应用服务。

  • 除了完成服务的组合和编排外,应用服务内还可以完成安全认证、权限校验、初步的数据校验和分布式事务控制等功能。

  • 为了实现微服务内聚合之间的解耦,聚合之间的服务调用和数据交互应通过应用服务来完成。

  • 原则上我们应该禁止聚合之间的领域服务直接调用和聚合之间的数据表关联

用户接口层:

  • 用户接口层是前端应用和微服务之间服务访问和数据交换的桥梁。

    • 它处理前端发送的 Restful 请求和解析用户输入的配置文件等,将数据传递给应用层。

    • 获取应用服务的数据后,进行数据组装,向前端提供数据服务。

  • Facade 服务分为接口和实现两个部分。

  • 完成服务定向,DO 与 DTO 数据的转换和组装,实现前端与应用层数据的转换和交换。

11

数据对象视图

数据持久化对象 PO(Persistent Object):

  • 与数据库结构映射,是数据持久化过程中的数据载体。

领域对象 DO(Domain Object):

  • 微服务运行时的实体,是核心业务的载体。

数据传输对象 DTO(Data Transfer Object):

  • 用于前端与应用层或者微服务之间的数据组装和传输,是应用之间数据传输的载体。

视图对象 VO(View Object):

  • 用于封装展示层指定页面或组件的数据。

基础层:

  • 基础层的主要对象是 PO 对象。
  • 当 DO 数据需要持久化时,仓储服务会将 DO 转换为 PO 对象,完成数据库持久化操作。
  • 当 DO 数据需要初始化时,仓储服务从数据库获取数据形成 PO 对象,并将 PO 转换为 DO,完成数据初始化。

领域层:

  • 领域层的主要对象是 DO 对象。
  • DO 是实体和值对象的数据和业务行为载体,承载着基础的核心业务逻辑。
  • 通过 DO 和 PO 转换,可以完成数据持久化和初始化。

应用层:

  • 应用层的主要对象是 DO 对象。
  • 如果需要调用其它微服务的应用服务,DO 会转换为 DTO,完成跨微服务的数据组装和传输。
  • 用户接口层先完成 DTO 到 DO 的转换,然后应用服务接收 DO 进行业务处理。
  • 如果 DTO 与 DO 是一对多的关系,这时就需要进行 DO 数据重组。

用户接口层:

  • 完成 DO 和 DTO 的互转,完成微服务与前端应用数据交互及转换。
  • Facade 服务会对多个 DO 对象进行组装,转换为 DTO 对象,向前端应用完成数据转换和传输。

前端应用:

  • 前端应用主要是 VO 对象。
  • 展现层使用 VO 进行界面展示,通过用户接口层与应用层采用 DTO 对象进行数据交互。

11

防腐层

防腐层(Anti-Corruption Layer)思想:

  • 通过引入一个间接的层,可以有效隔离限界上下文之间的耦合。
  • 防腐层往往属于下游限界上下文,用以隔绝上游限界上下文可能发生的变化。

即使上游发生了变化,影响的也仅仅是防腐层中的单一变化,只要防腐层的接口不变,下游限界上下文的其他实现就不会受到影响。

  • 比如用户订单微服务本地增加一个订单支付Service的Feign接口。
  • 这样用户订单Service就像本地调用一样调用支付Service,再通过这个Feign接口实现远程调用,这样的设计叫做防腐层设计。

缺点是代码会重复,但解耦彻底。

11

充血模型和贫血模型:

贫血模型:

实体不带有任何行为方法,也不带有聚合关联关系,作用基本相当于值对象(ValueObject),仅作为值传递的对象。

和传统三层项目架构中的实体具有相同作用,不建议使用。

  • 一般使用的DTO就可以被当做是值对象。

充血模型:

实体中带有具有行为方法和聚合关联关系,行为方法是说create、save、delete等封装了一类可以指代行为的方法。

比如在用户实体对象中具有用户组实体的引用,这样当我们需要操作用户组时,只通过用户实体进行操作就可以。

工程实践中,建议采用充血模型,好处是隐藏胶水代码,提升代码可读性,使关注点聚焦于业务实现。