←返回首页
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)组成,如
UserDao和UserDaoImpl。 - 开发笔记:
- 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 之间的繁琐转换。
