请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

SpringBoot中VO,DTO,DO,PO的概念、区别和用处

[复制链接]
查看: 748|回复: 3

10

主题

32

帖子

54

积分

等待验证会员

积分
54
发表于 2019-5-19 23:18 | 显示全部楼层 |阅读模式
VO(View Object):视图层,用于展现层,它的感化是把某个指定页面(或组件)的所稀有据封装起来。
DTO(Data Transfer Object):数据传输工具,这个概念来历于J2EE的设想形式,本来的目标时为了EJB的散布式利用供给粗粒度的数据实体,以削减散布式条用的次数,从而进步散布式挪用的性能和下降收集负载,但在这里,我泛指用于展现层与办事层之间的数据传输工具。
DO(Domain Object):范畴工具,就是从现实天下中笼统出来的无形或无形的营业实体。
PO(Persistent Object):持久化工具,他跟持久层(凡是是关系型数据库)的数据结构构成逐一对应的映照关系,假如持久层是关系型数据库,那末,数据表中的每个字段(或多少个)就对应PO的一个(或多少个)属性。
模子:
下面以一个时序图建立简单模子来描写上述工具在三层架构利用中的位置


image

  • 用户发出请求(能够是填写表单),表单的数据在展现层被婚配为VO。
  • 展现层把VO转换为办事层对应方式所要求的DTO,传输给办事层。
  • 办事层首先按照DTO的数据机关(或重建)一个DO,挪用DO的营业方式完成具体营业。
  • 办事层把DO转换为持久层对应的PO(可以利用ORM工具,也可以不用),挪用持久层的持久化方式,把PO传递给它,完成持久化操纵。
  • 对于一个逆向操纵,如读取数据,也是用类似的方式转换和传递,略。
VO与DTO的区分
1.大师能够会有个疑问(在笔者介入的项目中,很多法式员也有不异的迷惑):既然DTO是展现层与办事层之间传递数据的工具,为什么还需要一个VO呢?对!对于绝大部分的利用处景来说,DTO和VO的属性值根基是分歧的,而且他们凡是都是POJO,是以没需要画蛇添足,但不要忘记这是实现层面的思维,对于设想层面来说,概念上还是应当存在VO和DTO,由于两者有着本质的区分,DTO代表办事层需要接收的数据和返回的数据,而VO代表展现层需要显现的数据。
2.用一个例子来说明能够会比力轻易了解:例如办事层有一个getUser的方式返回一个系统用户,其中有一个属性是gender(性别),对于办事层来说,它只从语义上界说:1-男性,2-女性,0-未指定,而对于展现层来说,它能够需要用“帅哥”代表男性,用“美男”代表女性,用“奥秘”代表未指定。说到这里,能够你还会辩驳,在办事层间接就返回“帅哥美男”不就行了吗?对于大部分利用来说,这不是题目,但设想一下,假如需求答应客户可以定制气概,而分歧气概对于“性别”的表示方式纷歧样,又大概这个办事同时供多个客户端利用(分歧门户),而分歧的客户端对于表示层的要求有所分歧,那末,题目就来了。再者,回到设想层面上分析,从职责单一原则来看,办事层只负责营业,与具体的表示形式无关,是以,它返回的DTO,不应当出现与表示形式的耦合。
3.理论归理论,这到底还是分析设想层面的思维,能否在实现层面必须这样做呢?一刀切的做法常常会得失相当,下面我顿时会分析利用中若何做出正确的挑选。
VO与DTO的利用
上面只是用了一个简单的例子来说明VO与DTO在概念上的区分,本节将会告诉你若何在利用中做出正确的挑选。
在以下才场景中,我们可以斟酌把VO与DTO二合为一(留意:是实现层面):


  • 当需求很是清楚稳定,而且客户端很明白只要一个的时辰,没有需要把VO和DTO区分隔来,这时辰VO可以退隐,用一个DTO即可,为什么是VO退隐而不是DTO?回到设想层面,办事层的职责仍然不因该与展现层耦合,所以,对于前面的例子,你很轻易了解,DTO对于“性别”来说,仍然不能用“帅哥美男”,这个转换应当依靠与页面的剧本(如javaScript)或其他机制(JSTL,EL,CSS)。
  • 即使客户端可以停止定制,大概存在多个分歧的客户端,假如客户端可以用某种技术(剧本或其他机制)实现转换,一样可以让VO隐退。
以了局景需要优先斟酌VO,DTO并存:

  • 上述场景的背面场景
  • 由于某种技术缘由,比如某个框架(如Flex)供给自动把POJO转换为UI中某些FieId时,可以斟酌在实现层面界说出VO,这个这个权衡完全取决于利用框架的自动转换才能带来的开辟和保护效力提升与设想多一个VO所多做的工作带来的开辟和保护效力的下降之间的对照。
  • 假如页面出现一个“大视图”,而组成这个大视图的所稀有据需要挪用多个办事,返回多个DTO来组装(固然,这一样可以经过办事层供给一次性返回一个大视图的DTO来取代,但在办事层供给一个这样的方式能否合适,需要在设想层面停止权衡)。
DTO与DO的区分
首先是概念上的区分,DTO是展现层和办事层之间的数据传输工具(可以以为是两者之间的协议),而DO是对现实天下各类营业脚色的笼统,这就引出了两者在数据上的区分,例如UserInfo和User(对于DTO和DO的命名法则,请拜见笔者前面的一篇博文),对于一个getUser方式来说,本质上它永久不应当返回用户的密码,是以UserInfo最少比User少一个password的数据。而在范畴驱动设想中,正如第一篇系列文章所说,DO不是简单的POJO,它具有范畴营业逻辑。
DTO与DO的利用
1.从上一节的例子中,仔细的读者能够会发现题目:既然getUser方式返回的UserInfo不应当包括password,那末就不应当存在password这个属性界说,但假如同时有一个createUser的方式,传入的UserInfo需要包括用户的password,怎样办?在设想层面,展现层向办事层传递的DTO与办事层返回给展现层的DTO在概念上是分歧的,但在实现层面,我们凡是很少会这样做(界说两个UserInfo,甚至更多),由于这样做并不见得很明智,我们完全可以设想一个完全兼容的DTO,在办事层接收数据的时辰,不应由展现层设备的属性(如定单的总价应当由其单价、数目、折扣等决议),不管展现层能否设备,办事层都一概疏忽,而在办事层返回数据时,不应返回的数据(如用户密码),就不设备对应的属性。
2.对于DO来说,还有一点需要说明:为什么不在办事层中间接返回DO呢?这样可以省去DTO的编码和转换工作,缘由以下:


  • 两者在本质上的区分能够致使相互并不逐一对应,一个DTO能够对应多个DO,反之亦然,甚至两者存在多对多的关系。
  • DO具有一些不应当让展现层晓得的数据。
  • DO具有营业方式,假如间接把DO传递给展现层,展现层的代码便可以绕过办事层间接挪用它不应当拜候的操纵,对于基于AOP阻挡办事层来停止拜候控制的机制来说,这题目尤其突出,而在展现层挪用DO的营业方式也会由于事务的题目,让事务难以控制。
  • 对于某些ORM框架(如Hibernate)来说,凡是会利用“提早加载”技术,假如间接把DO表露给展现层,对于大部分情况,展现层不在事务范围之内(Open session in view在大部分情况下不是一种值得推重的设想),假如其尝试在Session封闭的情况下获得一个未加载的关联工具,会出现运转时异常(对于Hibernate来说,就是LazyInitiliaztionException)。
  • 从设想层面来说,展现层依靠于办事层,办事层依靠于范畴层,假如把DO表露进来,就会致使展现层间接依靠于范畴层,这虽然仍然是单向依靠,但这类跨层依靠会致使不需要的耦合。
对于DTO来说,也有一点必须停止说明,就是DTO应当是一个“扁平的二维工具”,举个例子来说明:假如User会关联多少个其他实体(例如Address、Account、Region等),那末getUser()返回的UserInfo,能否就需要把其关联的工具的DTO都一并返回呢?假如这样的话,必定致使数据传输量的大增,对于散布式利用来说,由于触及数据在收集上的传输、序列化和反序列化,这类设想更不成接管。假如getUser除了要返回User的根基信息外,还需要返回一个AccountId、AccountName、RegionId、RegionName,那末,请把这些属性界说到UserInfo中,把一个“立体”的工具树“压扁”成一个“扁平的二维工具”,笔者今朝介入的项目是一个散布式系统,该系统不管三七二十一,把一个工具的一切关联工具都转换为不异结构的DTO工具树并返回,致使性能很是的慢。
DO与PO的区分
DO和PO在绝大部分情况下是逐一对应的,PO是只含有get/set方式的POJO,但某些场景还是能反应出两者在概念上存在本质的区分:


  • DO在某些场景下不需要停止显式的持久化,例如操纵战略形式设想的商品折扣战略,会衍生出折扣战略的接口和分歧折扣战略实现类,这些折扣战略实现类可以算是DO,但它们只驻留在静态内存,不需要持久化到持久层,是以,这类DO是不存在对应的PO的。
  • 一样的事理,某些场景下,PO也没有对应的DO,例如教员Teacher和门生Student存在多对多的关系,在关系数据库中,这类关系需要表示为一其中心表,也就对应有一个TeacherAndStudentPO的PO,但这个PO在营业范畴没有任何现实的意义,它完全不能与任何DO对应上。这里要出格声明,并不是一切多对多关系都没有营业寄义,这跟具体营业场景有关,例如:两个PO之间的关系会影响具体营业,而且这类关系存在多品种型,那末这类多对多关系也应当表示为一个DO,又如:“脚色”与“资本”之间存在多对多关系,而这类关系很明显会表示为一个DO——“权限”。
  • 某些情况下,为了某种持久化战略大概性能的斟酌,一个PO能够对应多个DO,反之亦然。例如客户Customer有其联系信息Contacts,这里是两个一对一关系的DO,但能够出于性能的斟酌(极端情况,权作举例),为了削减数据库的毗连查询操纵,把Customer和Contacts两个DO数据合并到一张数据表中。反过来,假如一本图书Book,有一个属性是封面cover,但该属性是一副图片的二进制数据,而某些查询操纵不希望把cover一并加载,从而减轻磁盘IO开销,同时假定ORM框架不支持属性级此外提早加载,那末就需要斟酌把cover自力到一张数据表中去,这样就构成一个DO对应对个PO的情况。
  • PO的某些属性值对于DO没有任何意义,这些属性值能够是为领会决某些持久化战略而存在的数据,例如为了实现“悲观锁”,PO存在一个version的属性,这个version对于DO来说是没有任何营业意义的,它不应当在DO中存在。同理,DO中也能够存在不需要持久化的属性。
DO与PO的利用
由于ORM框架的功用很是强大而大行其道,而且JavaEE也推出了JPA标准,现在的营业利用开辟,根基上不需要区分DO与PO,PO完全可以经过JPA,Hibernate Annotations/hbm隐藏在DO当中。虽然如此,但有些题目我们还必须留意:


  • 对于DO中不需要持久化的属性,需要经过ORM显式的声明,如:在JPA中,可以操纵@Transient声明。
  • 对于PO中为了某种持久化战略而存在的属性,例如version,由于DO、PO合并了,必须在DO中声明,但由于这个属性对DO是没有任何营业意义的,需要让该属性对外隐藏起来,最多见的做法是把该属性的get/set方式私有化,甚至不供给get/set方式,但对于Hibernate来说,这需要出格留意,由于Hibernate从数据库读取数据转换为DO时,是操纵反射机制先挪用DO的空参数机关函数机关DO实例,然后再操纵JavaBean的标准反射出set方式来为每个属性设值,假如不显式声明set方式,或把set方式设备为private,城市致使Hibernate没法初始化DO,从而出现运转时异常,可行的做法是把属性的set方式设备为protected。
  • 对于一个DO对应多个PO,大概一个PO对应多个DO的场景,以及属性级此外提早加载,Hibernate都供给了很好的支持,请参考Hibnate的相关材料。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
http://michiganvacantproperty.org/cialis-20-mg/
回复

使用道具 举报

15

主题

45

帖子

76

积分

等待验证会员

积分
76
发表于 2019-5-19 22:30 | 显示全部楼层
项目中只用po加dto,不可能分那么细的,会类爆炸。
http://irc305.com/lioresal/
回复 支持 反对

使用道具 举报

8

主题

32

帖子

50

积分

等待验证会员

积分
50
发表于 2019-5-19 22:30 | 显示全部楼层
BO DAO DO POJO
http://irc305.com/viagra-generic/
回复 支持 反对

使用道具 举报

15

主题

49

帖子

75

积分

等待验证会员

积分
75
发表于 2019-5-19 22:30 | 显示全部楼层
少了DAO
http://redstonedart.org/100-mg-viagra-lowest-price
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 电脑,计算机,软件,程序,PC,播放器,数码,手机,通信 - 电脑杂谈 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表