目录

DO、DTO、BO、VO、POJO区别

DO、DTO、BO、VO、POJO区别:1、对象用途不同;2、对象职责和作用范围不同;3、对象属性和方法不同。对象用途不同是指DO用于映射数据库表,DTO用于传输数据,BO用于封装业务逻辑,VO用于向前端展示数据,POJO是一种无特殊语义的Java对象。

一、DO、DTO、BO、VO、POJO区别

1、对象用途不同

DO用于映射数据库表,DTO用于在服务和控制层之间传输数据,BO用于封装业务逻辑,VO用于向前端展示数据,POJO是一种普通的无特殊语义的Java对象。

2、对象职责和作用范围不同

每种对象的属性和方法都有所不同,有些属性和方法只在特定类型的对象中存在,例如数据传输对象通常没有业务逻辑。而且DO 只是数据的对象,不包含任何的操作,DTO可以进行数据传输,BO可以把业务逻辑封装为一个对象,这个对象可以包括一个或多个其它的对象,VO是视图模型,展示层对象,对应页面可以显示数据对象。

3、对象属性和方法不同

每种对象的职责和作用范围也有所不同,一般来说,DTO、BO和VO都是在业务逻辑层使用的,而DO主要用于与数据库交互,POJO则可以用于任何场景。

二、DO简介

DO(Data Object)是数据对象,它主要用于封装与数据库表相对应的映射关系。DO通常对应表中的一条记录,其中的属性对应表中的列。DO的属性与表的列一一对应,是与数据库交互的基础。

现在主要有两个版本:

  • 阿里巴巴的开发手册中的定义:DO(Data Object),这个等同于PO
  • 在DDD(Domain-Driven Design)领域驱动设计中的定义:DO(Domain Object),这个等同于BO

DO的特点:

  • 跟数据库表是一一对应的,一个DO数据是表的一条记录
  • 以前用Hibernate的时候PO用的很多,现在普遍喜欢用 DO,这个看各个公司自己的规范
  • DO只是数据的对象,不包含任何的操作。举个例子,学生表是StudentDO,对学生表的增删改查等操作就是StudentDAO

三、DTO简介

DTO(Data Transfer Object)是数据传输对象,DTO主要用于在服务层和控制层之间传递数据。DTO和DO非常相似,但是DTO更加注重数据传输的效率和安全性,会根据不同的业务需求灵活选择需要传输的属性,不会无脑把全部属性都传输过去。

数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,泛指用于展示层与服务层之间的数据传输对象。DTO通常用于Controller和Service交互。

DTO的特点:

  • 在分布式系统中,系统之间可以通过DTO进行数据传输
  • DTO也可以在应用内部,核心层和应用层之间传递数据,DTO只是简单的数据传输,没有业务逻辑的处理
  • 有的场景,比如数据库表有10个字段,id(少数id)、version(版本号),gmt_create(记录创建时间)这些字段不需要对外提供,所以DTO 可以只取有含义的业务字段,DO是和数据库记录的一一映射,但是DTO只需要按照业务需要定义需要的字段

四、BO简介

BO(Business Object)是业务对象,它封装了与业务逻辑相关的数据和操作。业务对象通常包含多个DO或DTO对象,并在其基础上封装了一些计算、比较、判断等业务逻辑。业务层对象,是简单的真实世界的软件抽象,通常位于中间层。BO 的主要作用是把业务逻辑封装为一个对象,这个对象可以包括一个或多个其它的对象。也有认为BO就是PO的组合。

BO的特点:

  • 在领域模型中,BO是个非常重要的概念,BO是最小的业务单元
  • BO 包含数据对象(PO/DO)以及对数据的操作

五、VO简介

VO(View Object)是视图对象,它用于向前端展示数据。VO和DTO很相似,但是VO更加注重数据展示的灵活性,通常包含一些前端需要的展示逻辑和格式化操作。视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。VO就是展示用的数据,不管展示方式是网页,还是客户端,还是APP,只要是这个东西是让人看到的,这就叫VO。VO通常用于前端和服务端Controller交互。

VO和DTO的区别:

  • 字段不一样,VO根据需要会删减一些字段
  • 值不一样,VO会根据需要对DTO中的值进行展示业务的解释

在以下场景中,我们可以考虑把VO与DTO二合为一(注意:是实现层面):

  • 当需求非常清晰稳定,而且客户端很明确只有一个的时候,没有必要把VO和DTO区分开来,这时候VO可以退隐,用一个DTO即可,为什么是VO退隐而不是DTO?回到设计层面,服务层的职责依然不应该与展示层耦合
  • 即使客户端可以进行定制,或者存在多个不同的客户端,如果客户端能够用某种技术(脚本或其他机制)实现转换,同样可以让VO退隐

以下场景需要优先考虑VO、DTO并存:

  • 上述场景的反面场景
  • 因为某种技术原因,比如某个框架(如Flex)提供自动把POJO转换为UI中某些Field时,可以考虑在实现层面定义出VO,这个权衡完全取决于使用框架的自动转换能力带来的开发和维护效率提升与设计多一个VO所多做的事情带来的开发和维护效率的下降之间的比对
  • 如果页面出现一个“大视图”,而组成这个大视图的所有数据需要调用多个服务,返回多个DTO来组装(当然,这同样可以通过服务层提供一次性返回一个大视图的DTO来取代,但在服务层提供一个这样的方法是否合适,需要在设计层面进行权衡)

六、POJO简介

POJO(Plain Old Java Object)是一种普通的Java对象,它没有任何限制和框架,不依赖于任何第三方库或JavaEE标准。它通常指的是不具备任何框架性质和特殊语义的纯Java对象,它可以作为其它对象的基类,也可以包含其它对象。

POJO是纯粹的传统意义的 java 对象。就是说在一些 Object/Relation Mapping 工具中,能够做到维护数据库表记录的 persisent object 完全是一个符合 Java Bean 规范的纯 Java 对象,没有增加别的属性和方法。我的理解就是最基本的 Java Bean ,只有属性字段及 setter 和 getter 方法。POJO 可认为是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

延伸阅读1:VO与DO的关系

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

一站式研发项目管理平台 PingCode

一站式研发项目管理平台 PingCode

支持敏捷\瀑布、知识库、迭代计划&跟踪、需求、缺陷、测试管理,同时满足非研发团队的流程规划、项目管理和在线办公需要。