在Java开发过程中,我们会遇到很多以“O”结尾的类名,刚开始看的时候,傻傻分不清,不都是一个Java类吗?为什么还要分这么多种类,今天就让我们来看看他们各是做什么用的?
几种“O”的定义
POJO(plian ordinary java object)
简单普通的Java对象,就是最简单的Java对象,最基本的Java Bean只是在属性上加上get和set方法,POJO可转化为以下的PO、DTO、VO等,比如说:在service中传递的Java Bean就叫DTO。
PO(Persistent Object)
持久对象,与数据库表中字段一一对应,可以将我们使用较多的Entity对比与PO,一般一个表对应一个PO,直接与数据库的crud操作相关。
VO(Value Object)
VO有人理解为Value Object,也有人理解为View Object,无论是那种定义,其表达的意思是:表现层对象,用于业务层之间的数据传递,其作用与PO类似,但是其是与页面层相关,一般将页面层的数据封装成一个VO传递给页面,此处的VO可以继承与PO以减少冗余代码。
DTO(Data Trasfer Object)
数据传输对象,一般用于向外提供仅需的数据,此处类似于VO的作用,如从数据库中查询出有30个字段,但是接口所需其中的10个字段,那么可在此处将10个字段封装成一个DTO提供给外部接口,以隐藏数据层的字段,也可减少数据的传输,提高系统性能。
BO(Business Object)/DO(Domain Object)
业务对象/域对象,一般写在业务层,当业务逻辑比较复杂时,可能会用到比较多的业务对象,这样就可以将多个PO、VO封装成一个BO对象用于数据传递。
DAO(Data AccessObject)
数据访问对象,就是一般我们所说的DAO层,用于连接数据库与service层的桥梁,用于对数据的访问(不是对数据库的访问),并且持久化数据层对象。
几种“O”直接的区别:
VO与DTO的区别:
从上面的定义可以看到VO与DTO的差别很小,很多时候会有人产生疑惑:有必要搞这个来区分吗?
其实从实现层面来说,两者没有区别,但是从设计层面来说,、概念上还是应该存在VO和DTO,因为两者有着本质的区别,DTO代表服务层需要接收的数据和返回的数据,而VO代表展示层需要显示的数据。
引用例子:
例如:服务层有一个getUser的方法返回一个系统用户,其中有一个属性是gender(性别),对于服务层来说,它只从语义上定义:1-男性,2-女性,0-未指定,而对于展示层来说,它可能需要用“帅哥”代表男性,用“美女”代表女性,用“秘密”代表未指定。说到这里,可能你还会反驳,在服务层直接就返回“帅哥美女”不就行了吗?
对于大部分应用来说,这不是问题,但设想一下,如果需求允许客户可以定制风格,而不同风格对于“性别”的表现方式不一样,又或者这个服务同时供多个客户端使用(不同门户),而不同的客户端对于表现层的要求有所不同,那么,问题就来了。再者,回到设计层面上分析,从职责单一原则来看,服务层只负责业务,与具体的表现形式无关,因此,它返回的DTO,不应该出现与表现形式的耦合。
DTO与DO的区别
首先是概念上的区别,DTO是展示层和服务层之间的数据传输对象(可以认为是两者之间的协议),而DO是对现实世界各种业务角色的抽象,这就引出了两者在数据上的区别,例如UserInfo和User,对于一个getUser方法来说,本质上它永远不应该返回用户的密码,因此UserInfo至少比User少一个password的数据。而在领域驱动设计中,正如第一篇系列文章所说,DO不是简单的POJO,它具有领域业务逻辑。