剑轩

DTO与VO的区别

电脑版发表于:2019/4/26 11:40


概念


 VO(View Object):

      视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。


 DTO(Data Transfer Object):

      数据传输对象,泛指用于展示层与服务层之间的数据传输对象。


 PO(Persistent Object):

      持久化对象,就是和数据库保持一致的对象


VO与DTO的区别


1:针对的点不一样

VO   :  针对的是视图层,拿去就是直接展示数据

DTO  :   针对的是各种之间的数据传递,拿去显示之前可能还会进行数据加工


所以从广义上来说:

    层与层之间的传输都可以叫DTO,都可以叫数据传输对象。控制器给视图传递对象,其实也是数据传输,所以也可以叫dto。

    只是由于它们之间传递的对象,是用于显示,所以我们又给他取了另外一个更加针对性名字叫vo


在强行解释一波:

    大家可能会有个疑问(在笔者参与的项目中,很多程序员也有相同的疑惑):既然DTO是展示层与服务层之间传递数据的对象,为什么还需要一个VO呢?对!对于绝大部分的应用场景来说,DTO和VO的属性值基本是一致的,因此没必要多此一举,但不要忘记这是实现层面的思维,对于设计层面来说,概念上还是应该存在VO和DTO,因为两者有着本质的区别,DTO代表服务层需要接收的数据和返回的数据,而VO代表展示层需要显示的数据。


       用一个例子来说明可能会比较容易理解:例如服务层有一个getUser的方法返回一个系统用户,其中有一个属性是gender(性别),对于服务层来说,它只从语义上定义:1-男性,2-女性,0-未指定,而对于展示层来说,它可能需要用“帅哥”代表男性,用“美女”代表女性,用“秘密”代表未指定。说到这里,可能你还会反驳,在服务层直接就返回“帅哥美女”不就行了吗?对于大部分应用来说,这不是问题,但设想一下,如果需求允许客户可以定制风格,而不同风格对于“性别”的表现方式不一样,又或者这个服务同时供多个客户端使用(不同门户),而不同的客户端对于表现层的要求有所不同,那么,问题就来了。再者,回到设计层面上分析,从职责单一原则来看,服务层只负责业务,与具体的表现形式无关,因此,它返回的DTO,不应该出现与表现形式的耦合。

    tip: 如果是单一项目 ,其实可以不用分得那么细,从数据库拿出来就是为了展示了,而不是还要给其他层提供服务 


在一个单一的项目中常用的做法



1:省略dto  

      就是把数据取出来的对象,直接返回给控制器层,然后控制器层进行数据加工变成vo,在交给前台。

      优点:通用性好,因为取出来的就是全部的字段,在控制器中进行数据加工,可以取到想要的字段,而传输层逻辑不用修改

                例如做基础增删改查代码的生成就很方便

      缺点:会查询全表,影响效率。当然也可以使用其他方法解决

      无图无真相:

    

    

2:省略vo

      数据库取出来部分字段,放入dto,然后dto传递到控制器,在传递到view中去,也就是说dto充当了各层直接的数据传输

      优点: 可以返回自己想要的数据,不同的业务针对性查询 ,不同业务耦合性更低

      缺点: 通用性差一点,不同的业务逻辑各层需要独立的写,果从单一职责来看不应该dto 直接丢视图

      如图:

      


3:dto,vo同时存在

     dto传递到控制器,控制器在进行一次数据加工,然后传递到view中去

     他们同时存在,然后不同的业务逻辑中可以选择,省略dto或者vo或者两同时使用

    

     当然这只是一种情况,其实还可以把各层的dto分得更细一点!这里就不讨论了



在分布式项目中vo,dto,po的做法


  分布式项目中,由于项目是独立的,model都是自己项目中的,所以就不存在省略了



  



   


个人见解,轻喷



关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢