对于这些概念,网上众说纷纭。不要纠结他是什么,不要纠结DTO与VO的区别是什么。在实际编码过程中,按照你们研发组的规范来做就好了。可能你觉得划分的比较细,专业性比较强。但用处不大。
1. 概念
如下概念是我摘要解释比较合理的。望周知。
- VO(View Object): 视图对象,用于展示层,这很好理解,就是页面所需数据封装。
- VO(Value Object): 值对象,跟引用对象(Reference Object)做区分。 类似 int,long这种类型,值一样他们就一样,但是本身又是一个Object。
- DTO(Data Transfer Object): 数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载。(个人理解:原先需要获取用户信息和用户订单需要调用俩个接口,将返回数据整合为一个DTO,调用一次就可以获取所有数据)
- Entity: 实体类,一般与持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应Entity的一个(或若干个)属性。
2. 区别
概念是我抄的。具体的区别关系,我举个例子来说明。
需求:返回某个用户信息和其账号订单数量。
- 首先我们需要查询数据库获取用户信息和账号订单数量,但是无论是用户信息对应的Entity还是账号订单对应的Entity都不能满足我们的需要。
- 这时我们创建一个DTO继承用户信息Entity(正常来讲还是不要继承,重写一份),扩展订单数量属性。然后无论是连表还是单独查询,将查询到数据放到DTO中就好了。
- 处理完数据该返回了。但是页面中需要显示用户的性别,可是我们DTO中存的是数字0和1,这咋办,那我们就在创建一个VO,将DTO转换为VO(将其中的性别转换为男女汉字),用来返回页面数据。
阿里巴巴开发手册:
领域模型命名规约
1) 数据对象:xxxDO,xxx 即为数据表名。
2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
3) 展示对象:xxxVO,xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
可以看到,人家阿里的规范中VO就是View Object。也或者说View Object = Value Object。
疑问:
- 我们直接在DTO中转换为汉字就好了啊。
答:万万不可,你在Service层处理数据的时候,或者分布式调用的时候。你用男女在这乱传,这不乱套了吗?就算你可以传,有的需求需要判断男女,if(‘男’.equals(gender))。如果我页面需要显示靓仔,再将所有代码改为if(‘靓仔’.equals(gender)),那这不又乱套了吗。 - 就算你说的对,那我们直接不处理,让前端处理不就好了。
答:可以,确定固定范围的值,可以给前端处理,反正就0和1 。但是如果我不确定呢,这个值有n个呢?高的,瘦的,胖的,矮的。这前端想想头都大。肯定会骂:你给我什么显示什么,不管了! - 那好,你都这样说了,那我直接在返回数据的时候做下转换就好了吧,那这样VO也用不到啊。
答:如果某个页面也需要这个DTO,但是他不需要性别这个数据。怎么办?用不用先返回再说,那这样是不是泄露了这个用户的性别信息。返回处理为空,那这个字段返回不是浪费吗?返回无用字段。 - 如果像第二条所说,固定范围内的值,可以直接返回。但是我习惯用VO命名,不想用DTO。
答:怎么说呢,VO(View Object),全称都说了视图对象,放到Service层中,是不是不太好啊。这不就相当于服务层与展示层耦合了?
看到这了,反之发送请求的时候,比如新增一个用户。就使用DTO接收数据。因为无论前端显示靓仔还是男,我们只需要1这个数字!
总结
有的人会想,VO到底代表哪一种。不要被这些概念混淆,我上面写的也只是帮助理解概念。在实际的编码当中,一个Entity关联表实体类,Entity满足不了页面所需数据,在加个VO去扩展所需属性就可以了!多么简单的事情。搞这么复杂干啥啊!
适合自己的才是最好的!!!
个人整理参考,存在纰漏或错误的地方,欢迎各位批评指正!