写点什么

DO、DTO、BO、VO、POJO 区别

发布于: 2021 年 02 月 16 日

不知道大家在自己的系统中发现很多类都是以 VO、DTO、DO 结尾的类,这些存储数据的简单类,有什么作用呢?


我理解有二个作用:


  • 一般稍大的系统都是分层设计的,最底层是数据存储层,数据库,最上层是对外提供接口调用的应用层,那每一层都有关联的数据对象,所以需要做相应的区分。

  • 让类语义更明确,很容易知道类的含义。


定义


先来看看阿里巴巴开发规约的定义:


POJO(Plain Ordinary Java Object):在本规约中,POJO 专指只有 setter/getter/toString 的简单类,包括 DO/DTO/BO/VO 等。


【参考】分层领域模型规约:

>

- DO(Data Object):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。

- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。

- BO(Business Object):业务对象。可以由 Service 层输出的封装业务逻辑的对象。

- Query:数据查询对象,各层接收上层的查询请求。额外规定:【强制】超过 2 个参数的查询封装,禁止使用 Map 类来传输。

- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。

>

—《阿里巴巴 Java 开发规约》


详细各个词的定义:


DAO: Data Acess Object,数据访问对象,这个我们不陌生,跟数据库打交道的系统都会有这样的 DAO 类,主要的作用:


  • 封装对数据库的访问,常规的增删改查(CRUD 操作)都通过 DAO 来实现。


PO/DO: Persistent Object / Data Object,持久对象 / 数据对象。


  1. 跟数据库表是一一对应的,一个 PO/DO 数据是表的一条记录。


  1. 以前用 Hibernate 的时候 PO 用的很多,现在普遍喜欢用 DO,这个看各个公司自己的规范。


  1. PO / DO 只是数据的对象,不包含任何的操作。举个例子,学生表是 StudentDO,对学生表的增删改查等操作就是 StudentDAO。


DTO:Data Transfer Object,数据传输对象


  1. 在分布式系统中,系统之间可以通过 DTO 进行数据传输;

  2. DTO 也可以在应用内部,核心层和应用层之间传递数据,DTO 只是简单的数据传输,没有业务逻辑的处理;

  3. 有的场景,比如数据库表有 10 个字段,id(唯一 id)、version(版本号),gmt_create(记录创建时间) 这些字段不需要对外提供,所以 DTO 可以只取有含义的业务字段,DO 是和数据库记录的一一映射,但是 DTO 只需要按照业务需要定义需要的字段。


BO : Business Object, 业务对象


BO 主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。


  1. 在领域模型中,BO 是个非常重要的概念, BO 是最小的业务单元。


  1. BO 包含数据对象(PO/DO)以及对数据的操作。


VO: View Object, 视图模型,展示层对象


对应页面显示(web 页面/移动端 H5/Native 视图)的数据对象。


  1. 举个例子,DTO 中时间 Date 格式,或者是 yyyyMMddHHmmss 的字符串,但是 VO 需要的是前端展示的格式,需要转成”yyyy 年 MM 月 dd 月";


实践


讲了这么多概念,我们再看下实操,先说命名:


领域模型命名规约

1) 数据对象:xxxDO,xxx 即为数据表名。

2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。

3) 展示对象:xxxVO,xxx 一般为网页名称。

4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO


再以学生档案管理系统为例,我们现在需要做个学生档案管理的后台系统,按照上面的定义,我们能定义出以下一些对象:


如下图所示:



DB 层这里应该叫存储层,这里只列了 DB,还有类似 HBase、Redis,泛指储存数据。


以 Student 表为例,DB 层负责存储。


  1. DAO 层提供了查询、删除、写入的接口;


  1. DO 就是 DAO 操作的对象,这里是 StudentDO,有时候也会省略 DO,直接写 Student;

  2. service 层或 core 层是做业务逻辑处理的,比如查询接口,根据学生学号调用 DAO 层获取 Student 信息,之后做一次数据裁剪,只取业务字段,例如版本号、自增 id、数据库记录创建时间等非业务字段不取,获取一个 StudentDTO,然后查询学生档案相关的 ProfileDTO,组装成 ProfileBO,作为档案领域模型;

  3. 业务层从 service 层拿到这个 BO,对 BO 做一个视图转化,转成 VO 视图对象,提供给前端负责展示。


大学刚毕业实习那会写了一个业务层直接调用 DAO 层的代码,觉得中间要经过服务层、核心层过于繁琐,字段都差不多,但是后面被 Team Leader 指导了。


VO(视图) 和 DO(数据模型)都可能会随着需求变化,软件设计的原则是降低耦合,一杆到底这种设计就是强耦合(把视图和数据直接绑定),DO 变化的时候因为 DTO(数据传输对象)、BO(领域模型)的存在,不需要修改 VO,VO 修改也同样不需要修改 DO 数据模型。


另外为金三银四准备的 100 道高频 Java 面试题,给大家汇报一下进度,目前 70 道已经 OK 了,还剩 30 道,届时我会放到后台文档中,公众号后台回复 100 获取《100 道高频 Java 面试题》,大家如果有什么遇到的面试题可以后台发给我,如果觉得好可以收录。


发布于: 2021 年 02 月 16 日阅读数: 20
用户头像

还未添加个人签名 2018.03.26 加入

还未添加个人简介

评论

发布
暂无评论
DO、DTO、BO、VO、POJO区别