DO,VO,DTO 傻傻分不清楚【名词解释篇】

Java 里有很多"欧",这些"欧"看得一头雾水,先对齐一下颗粒度做个名词(黑话)解释(翻译成人话)。

🍇 PO(Persistant Object)持久对象

用于表示数据库中的一条记录映射成的 java 对象。仅仅用于表示数据,没有任何数据操作。因为要和数据库表字段对应,所以类中应该都是基本数据类型和String,而不是更复杂的类型。可以理解是一个PO就是数据库中的一条记录。

通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

🍈 DO(Data Object)数据对象

数据对象,与数据库表结构一一对应,通过 DAO 层向上传输数据对象,属性和 PO 中的基本一致。

PS:看了很多文章,社区也有很多人回答,发现 PO 和 BO 一般用一个就行了,传统意义上命名为 PO,如果编程风格上往 DDD 靠拢就命名成 DO。名字不同而已,没什么大的讲究。

🍉 BO(Business Object)业务对象

较复杂的业务对象,会参与业务逻辑的处理操作,里面可能包含多个类,主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。例如用户可以拥有宠物,在这里把用户对应一个 PO、宠物对应一个 PO,那么建立一个对应的 BO 对象来处理用户和宠物的关系,每个 BO 都包含用户 PO 和宠物 PO,而处理逻辑时针对 BO 去处理。

通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

例如(注:UserPet 都是 PO 对象,但会放进 BO 中,形成一个复杂的业务对象):

java 复制代码
public class UserPetBo {
    private User user;
    private Pet pet;
    
    public UserPetBo() {
    }
}

再补充一点,BO 包括了业务逻辑,常常封装了对 DAO、RPC 等的调用,可以进行 PO 与 VO/DTO 之间的转换。通常位于 Service 层,但要区别于直接对外提供服务的服务层:

  • BO 提供了基本业务单元的基本业务操作,在设计上属于被服务层业务流程调用的对象。
  • 一个业务流程可能需要调用多个 BO 来完成。

比如一个简历,有教育经历、工作经历、社会关系等等。我们可以把教育经历对应一个 PO,工作经历对应一个 PO,社会关系对应一个 PO。建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些PO。这样处理业务逻辑时,我们就可以针对 BO 去处理。

🍊 VO(Value Object)表现对象

VO 对象主要用于前端界面显示的数据,是与前端进行交互的 Java 对象。为什么不用 PO 传递数据呢,因为PO 包括数据库表中的所有字段,对于前端来说我们只需要显示一部分字段就可以了,例如我们的用户表 user 中的 password 字段是没有必要也不能显示在前端界面的。

通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

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

数据传输对象是在传递给前端时使用的,如一张表有 100 个字段,那么对应的 PO 就有 100 个属性,但是我们的前端界面只需要显示 10 个字段,所以我们没必要把所有字段的 PO 对象传递到客户端,我们只需要把只有这 10 个属性的 DTO 对象传递到客户端,不会暴露服务端的表结构,到达客户端后,如果这个对象用于界面表示,那么它的身份就是 VO 对象。

DTO 和 VO 概念相似,通常情况下字段也基本一致。但有所不同,DTO 表示一个数据传输对象,是在服务端用于不同服务或不同层之间的数据传输,例如 DAO 层到 Service 层,Service 层到 Controller 层;而VO是在客户端浏览器显示的表现对象,用于在浏览器界面数据的显示。

但 DTO 除了可以充当 VO 的功能(把数据传递给客户端)以外,又有一些不同,它涉及的面更广。上面说的是

rust 复制代码
DAO 层 -> Service 层 -> Controller 层

那么反过来呢,比如在 Controller 层传递到 Service 层,这里 DTO 也可以作为传输对象。

通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

🍋‍🟩 DAO(Data access object)数据访问对象

虽然名字也带"欧",但和上面几个"欧"区别最大,基本没有互相转化的可能性和必要。

主要用来封装对数据库的访问,例如 UserDao 封装的就是对 user 表的增删改查操作。

通过它可以把 POJO 持久化为 PO,用 PO 组装出来 VO、DTO;

DAO 一般在持久层,完全封装数据库操作,对外暴露的方法的使得上层不需要关注数据库的相关信息,只需要插入、删除、更新、查询即可。

🍌 POJO(Plain ordinary java object)简单java 对象

表示一个个简单的 Java 对象:

  • PO、VO、DTO 都是典型的 POJO。
  • DAO 和 BO 一般不是 POJO,只是提供了一些调用方法。

🍒​ 举个荔枝

有一个博客系统,数据库中存储了很多篇博客。我们会做如下设计:

  • 数据库表:表中的博客包括编号、博客标题、博客内容、博客标签、博客分类、博客状态、创建时间、修改时间等。
  • PO:包括编号、博客标题、博客内容、博客标签、博客分类、博客状态、创建时间、修改时间等。(与数据库表中的字段一致)
  • VO:在客户端浏览器展示的页面数据,博客标题、博客内容、博客标签、博客分类、创建时间、上一篇博客URL、下一篇博客URL。
  • DTO:在服务端数据传输的对象,编号、博客标题、博客内容、博客标签、博客分类、创建时间、上一篇博客编号、下一篇博客编号。
  • DAO:数据库增删改查的方法,例如新增博客、删除博客、查询所有博客、更新博客。
  • BO:基本业务操作,如管理分类、管理标签、修改博客状态等,是我们常说的 Service 层操作。

总结

引用网上的一张图来表示各个"欧"之间的传递关系:

🌹 鸣谢

感谢这个沸点评论区的大佬们,你们的回答帮助很大,撒花*★,°* :.☆( ̄▽ ̄)/$:.°★

以上内容总结于网络文章 + 论坛坛友的实际工作。

相关推荐
八苦4 分钟前
ACME协议
后端
陈随易4 分钟前
牛回,速归!VSCode开启AI的野兽模式究竟有多强
前端·后端·程序员
A_氼乚6 分钟前
封装Spring Boot Redisson分布式锁
后端
高松燈1 小时前
开发中常见的String的判空场景总结
后端
程序员NEO2 小时前
我只说需求,AI 全程托管,代码自己长出来了!
人工智能·后端
白露与泡影2 小时前
Spring Boot 优雅实现多租户架构!
spring boot·后端·架构
编写美好前程2 小时前
springboot项目如何写出优雅的service?
java·spring boot·后端
Aurora_NeAr2 小时前
大数据之路:阿里巴巴大数据实践——实时技术与数据服务
大数据·后端
过客随尘2 小时前
Mysql RR事务隔离级别引发的生产Bug,你中招了吗?
后端·mysql
知其然亦知其所以然2 小时前
社招 MySQL 面试官问我:InnoDB 的 4 大特性?我靠这 4 个故事一战封神!
后端·mysql·面试