返回首页
316 2 分钟2025-12-16Software Architecture#DDD / System Design / Backend / Architecture / Java

DDD 领域模型对象详解:从 BO 到 DAO

DDD 领域模型对象详解

概述

在软件开发(特别是遵循领域驱动设计 DDD 或分层架构)中,为了实现高内聚低耦合,我们将数据在不同层级间流转时封装为不同类型的对象。理解这些对象的定义与职责,是构建清晰、可维护架构的基础。

核心模型对象定义

1. BO (Business Object) - 业务对象

业务对象代表一个具体的业务实体,是业务逻辑的核心载体。

  • 定义: 封装了业务数据和业务逻辑的对象,可能由多个 PO 组合而成。
  • 职责: 处理核心业务规则。
  • 应用场景: Service 层
  • 开发笔记:
    • 主要在 Service 层中使用。
    • 负责具体的业务逻辑处理(非单纯的数据存取)。
    • 既然 BO 包含逻辑,那么 CRUD 的具体执行应下沉至 DAO 层。

2. VO (Value Object) - 值对象

主要用于展示层的数据对象,通常是不可变的。

  • 定义: 用于传递给前端页面进行展示的数据集合。
  • 职责: 仅包含页面需要的数据,属性与 UI 展示强相关。
  • 应用场景: View / Controller 层(向外输出)。
  • 开发笔记:
    • 是后端给前端页面的最终数据格式。
    • 可以继承 PO 或 DO,也可以重新定义,目的是隐藏不该暴露给前端的字段(如密码、内部状态码等)。

3. PO (Persistent Object) - 持久化对象

与数据库结构一一对应的“镜像”对象。

  • 定义: 数据库表结构的直接映射。
  • 职责: 承载数据库中的原始数据。
  • 应用场景: DAO / Infrastructure 层
  • 开发笔记:
    • 即通常所说的 Entity(实体类)。
    • 属性与数据库表的字段完全一致。
    • 一般不包含复杂的业务逻辑。

4. DO (Data Object) - 数据对象

在不同框架或理解中,DO 的定义略有差异,通常介于 PO 与 BO 之间。

  • 定义: 也是与数据库表结构对应的对象,但在某些上下文中包含一定的数据逻辑。
  • 职责: 数据隔离与基础逻辑限制。
  • 应用场景: DAO / Service 层
  • 开发笔记:
    • 在很多实践中,DO 等同于 PO。
    • 进阶用法:可以在 DO 中对实体类进行逻辑软限制(例如:字段值的合法性校验,如“年龄不能为负数”等基础数据完整性逻辑)。

5. DTO (Data Transfer Object) - 数据传输对象

用于不同层级或系统间传输数据的容器。

  • 定义: 纯粹的数据容器,不包含任何业务逻辑。
  • 职责: 降低层间耦合,优化网络传输。
  • 应用场景: Controller 层(接收参数)或 微服务调用
  • 开发笔记:
    • 前端页面传送给 Controller 层的数据包。
    • 典型用例:分页查询时的参数对象(包含 page, pageSize, filters 等)。

6. DAO (Data Access Object) - 数据访问对象

严格来说,DAO 属于一种设计模式或组件,而非单纯的数据载体,但常与上述对象并列讨论。

  • 定义: 封装对数据源(数据库)的访问操作。
  • 职责: 执行 CRUD(增删改查)。
  • 结构: 通常由接口(Interface)和实现类(Impl)组成,如 UserDaoUserDaoImpl
  • 开发笔记:
    • DAO 层只负责“搬运数据”,不处理复杂的业务逻辑。
    • BO 调用 DAO 来获取或持久化数据。

对象间的转换关系

在典型的分层架构中,数据流转通常遵循以下路径:

graph LR;
    subgraph "请求处理 (Request)"
    DTO["DTO (传输对象)"] --> BO["BO (业务对象)"];
    end
    
    subgraph "业务处理 (Process)"
    BO --> PO_DO["PO/DO (持久化对象)"];
    PO_DO --> BO;
    end
    
    subgraph "响应返回 (Response)"
    VO["VO (值对象)"] --> BO;
    BO --> VO;
    end

    style DTO fill:#f9f,stroke:#333,stroke-width:2px
    style BO fill:#bbf,stroke:#333,stroke-width:4px
    style PO_DO fill:#bfb,stroke:#333,stroke-width:2px
    style VO fill:#fbb,stroke:#333,stroke-width:2px

架构实践与思考

1. 职责分离 (Separation of Concerns)

  • Entity/PO: 纯粹的数据库映射。
  • DAO: 纯粹的数据操作接口。
  • BO: 纯粹的业务逻辑组合。
    这种分离使得代码结构清晰,易于维护。

2. 数据库解耦

BO (业务逻辑)DAO (数据访问) 分离是架构设计的关键点。

优势: 当底层数据库发生变更(例如从 MySQL 迁移到 PostgreSQL,或者表结构重构)时,只需要修改 DAO 层和 PO 的映射,而上层的核心业务逻辑(BO/Service)无需变动。

3. 使用建议

  • 明确边界: 严禁在 Controller 层直接操作 PO,也不建议将 PO 直接返回给前端(暴露表结构风险)。
  • 工具辅助: 合理使用对象映射工具(如 MapStruct, BeanUtils)来处理 DTO -> BO -> PO 之间的繁琐转换。
正在初始化...