`
peterwei
  • 浏览: 249503 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

VO(DTO)模式在分层架构设计中是否需要的扯淡

阅读更多
VO(DTO)模式在分层架构设计中是否需要的扯淡

Peter Wei


引子:

前两天,在内部讨论中。公司有一开发人员向我抛出问题:我们Web层和App应用层用DTO(VO)对象,没有直接用PO,你有什么好的建议?我自然知道他说这句话的意思,PO到DTO(VO)的不停转换,太麻烦,增加太多工作量了。因为我是负责系统架构的,他是想让我向上面CTO反映取消掉DTO对象。但现有的架构是原先就有的,而且在一定程度上,我也认为需要用DTO对象。所以最终没有全部取消。


概念扫盲

我们现在大多数的应用,我想都是基于分层架构的:
Web层(Struts2 or SpringMVC等)App应用层(Service)Dao层(ORM)DB

PO:也就是一般概念上的Domain Object,如hibernate 中的Entity.一般用于Service层--Dao层间的数据传输。

DTO(VO):也就是一般意义上的VO,封装后的对象。一般用于Web层—Service层间的数据传输入。


VO(DTO) VS PO
引子中开发人员是想用PO透传所有层。也就是共用PO,然后取消掉DTO。

1.PO透传的代码示例:

比如有一个Order的hibernate entity.
我们假设Order下还有Account等好几个对象和集合。

public class OrderAction{
	private Order order=new Order();
	private List<Order> orderList
	public String add(){
		orderService.add(order);
		return xx;
}

public String query(){
	orderList=orderService.find(Object param);
	return xx;
}
}

public class OrderService{
	
	public void add(Order){
		orderDao.saveOrUpdate(Order o);
}
	public List find(Object param){
		return orderDao.find(Object param);
}
}


2.用VO(DTO)模式的代码示例:

public class OrderService{
	
	public void add(OrderVO vo){
		Order order=new Order();
		Account account=new Account();
		
		account.setXX(vo.getXX);
		//一堆XX
		order.setAccount(account);
		//又一堆XX
		orderDao.saveOrUpdate(Order);
}
	public List<OrderVO> find(Object param){
		List list=orderDao.find(Object param){
			for(xxxx){
			//集合下的集合
			//更多的XX转换
			setXX
			setXX
}
}
}
}

PO的透传的优点一目了然,就是不用进行大量的数据对象转换,极大的减少开发人员的工作量。而且大多数PO和VO是重合的,属性什么都一样。我们知道虽然有BeanUtils等工具进行自动转换,但依然很繁琐。
BeanUtils.copyProperties(desc,src);


为什么用VO(DTO)

我在以前的工作过程中做过各种企业应用还有网站应用。大多数的项目,我们都用的是PO透传View,Action,Service,Dao层。但有两个项目中没用。

1.一个是联通的某OSS系统,该系统的基本技术架构是这样的:
Flex(Web层)BladeDSBusiness Facade(DTO)Service(Spring)Dao(hibernate)

我们一眼看出这是一个分布式的系统。也就是Flex和Java应用通迅的异构系统。在Flex和Java应用之间用DTO模式结合外观Facde模式就顺理成章,水道渠成了。为什么呢?因为两个进程间的通迅,复杂层级的Hibernate Domain Object不好直接传到Flex端,因为是用remote协议传输。Hibernate的lazy特性以及序列化都是个问题。所以加一个外观层进行PO到DTO的传输就很有必要了。

2.一个是一个电子商务网站,网站的基本技术架构是这样的:

有两部分,一部分是内部管理核心系统:
Flex应用Hessian Remote协议App Service(Sring)Dao(hibernate)

另一部分是电子商务系统,也就是对外的部分
Web应用(Jstl,jsp,SpringMVC)Hessian Remote协议 App Service(Sring)Dao(hibernate)

其中Flex应用单独部署一个工程,Web应用单独部署一个工程,App Service和Dao又部署一个工程。Flex和web应用都是单独通过hessian协议访问App应用。

我们来总结一下为什么要用DTO:
1. JavaEE各层之间解耦,这是从设计角度来说的。也就是说Domain Object(PO)直接封死在Dao层。高内聚,低耦合是我们追求的一个目标。但由于在一般的应用中大量的PO,VO转换,增加了工作量,也有些人说是过度设计。
2. 隔离变化。当在一些大型的应用场景以及Domain经常变化的系统里,View层可以只关注DTO对象,不用关心Domain层PO对象,如hibernate entity的不断变化。
3. 利于发挥个人技术特长,特别是按层来分工开发的团队。如有人专注于Web层,只做SpringMVC和界面这部分。还有人专门做Spring和Hibernate部分。两组的开发人员定义好接口数据就行,也就是DTO(VO)。我们当时做的电子商务网站就是这样的。
4. 当系统发展大后,扩展成各种前端界面后,可以有效隔离核心应用层。如又有web界面,又有swing的cs界面,又有手机客户端。
5. 当分层部署时,也就是Web层(jsp,Struts2)和App层(Spring,dao)在不同机器上时,用Remote协议通迅,DTO是必需的。如处理hibernate lazy load和序列化等问题。在电子商务应用中分层部署的主要好处是减少各层负载量,提高性能。
6. 在一些特定场景,如需要防火墙的地方,需要把核心数据层(Service,Dao,DB)放在防火墙内。

小结
综合以上所述,我认为VO(DTO)模式还是必需的,特别是考虑到以后扩展性的问题。但是在我们的团队中为了开发进度和避免对以前开发的功能影响,没有强制要求在Action和Service层间一定用DTO.但是新开发的功能模块要求用DTO模式,算是一种折中吧。以后系统大了之后再重构好了。要不然以后怎么有事做呢?哈哈。而且boss有时间压力在那。毕竟现在还没打算分层部署,够用就行,先不过度设计了。

其它牛人的一些观点:
参考:Martin Fowler的POEAA(企业应用架构模式)中分布式模式中的Remote Facade模式和DTO模式。

Rod Johnson在J2EE without ejb中是反对用DTO的。

欢迎拍砖,谢绝漫骂!
分享到:
评论
18 楼 peterwei 2011-04-24  
卡拉阿风 写道
既然是用了hibernate,还有种替代dto的办法,使用select new map()..

对于用map透传所有层的技巧,比之po,我更加不赞成使用。
17 楼 peterwei 2011-04-24  
silence1214 写道
个人也觉得DTO都低用不用还是根据实际情况来,有时候不需要分布,就是一个小应用,多余的DTO只会带来复杂度。你给的几个案例但是用着DTO蛮合适的。没有绝对的哈,知道有这么个架构思想,剩下来一切从需求出发吧

是这样的。
16 楼 peterwei 2011-04-24  
<div class="quote_title">skzr.org 写道</div>
<div class="quote_div">
<p>我做企业应用的,以前也听某某、某某谈论dto、vo、po甚至其他oo。<br>我认为最佳的实践:楼下两个基本上讲的是原则。</p>
<p> </p>
<p> </p>
<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff; margin: 8px;">
<div class="quote_title" style="font-weight: bold; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; padding: 5px;">yangyiqian 写道</div>
<div class="quote_div" style="margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; background-color: #fafafa; padding: 3px; border: 1px solid #cccccc;">首先我想说“存在就是真理”,DTO、PO绝对不是一个范畴的概念,<span style="color: #ff0000;">DTO!=PO</span>,所以也就谈不上谁代替谁的概念。当然了,你非要说老板就不能做员工的话吗?当然可以,不过这是做事的规矩吗?!<br><br><strong>一、DTO与PO的不对称关系决定了二者不能互相代替</strong><br>DTO与PO存在在映射关系,可能是多对一,也可能是一对多,最特殊的关系就是上面大家说的这种情况“一对一”。也就是在“一对一”的情况下可以实现DTO与PO的混用,而其他情况下,如果混用都需要PO进行冗余设计,考虑这些冗余设计会比直接的、简单的造一个新的DTO出现要耗费更多的脑细胞,同时这个东西又不利于后期维护,可以说“牵一发,动从上到下”。<br><strong>二、性能上决定了PO代替DTO是个蹩脚的设计</strong><br>PO是与数据库直接交互的对象,比如我要在页面上显示数据库中的数据,如果用PO来实现那么这个PO就得一直保持与数据库的连接,直到数据显示到页面上来。这样如果在service层有复杂运算的话,那么数据库方面的延时是非常可观的,而如果转换成DTO之后,数据库连接就可以尽快释放。所以从性能上来说应该使用DTO--当然对于性能不是很苛刻的情况下不用DTO也行 --不过,熟练的程序员应该养成按统一的方式做项目的习惯,我觉得这样会更高效。<br><br><br>
</div>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">最佳实践:</p>
<p style="margin: 0px;">软件是发展的,我只认设计中的bean,如果bean要持久化就有po的职责了,一切都只是手段而已</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;"><span style="line-height: 18px; font-family: Arial, sans-serif, Helvetica, Tahoma;">难道是ORM把我们绑架了!太在意po和dto这样的概念了,设计才是根本,满足设计的bean才是核心。</span></p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">就正如时刻要记住的技术是为了实现业务需求而用,很多人反过来用了,为了技术而技术,被技术忽悠。最简单、是人就可以看懂的实现才是好实现</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;"> </p>
</div>
</div>
<p> 我也说了,大多数的企业应用,是可以po从view-dao透传所有层的。但是一些特定场景,特别是分布式环境,异构环境,DTO模式还是很有必要存在的。PO和DTO的概念还是很有必要理清的。很多东西,由于个人的一些经验问题,接触得不多,往往很难一眼看清本质。特别是底层的人员,有时候会看不清楚一个设计为什么这样。所以我觉得讲讲,扫下盲是有必要的,特别是对团队内部的人来说。而不能什么都不让他们知道,只是强制执行。</p>
15 楼 peterwei 2011-04-24  
lookdd1 写道
开发网站就用网站的技术。。。别把JAVA EE的搞进来。你追不上那帮搞PHP的。。追不上那帮搞RAILS的。。。追不上就==死掉

你这个和这个没有关系吧?你要搞php可以搞呀。为什么搞网站不能javaee呢?
14 楼 peterwei 2011-04-24  
zym_nanako 写道
如果web层和service层分离的话,那么service之间的调用是远程方式还是本地方式?

一般都是远程协议,如rmi,hessian等,因为有可能是分开不同的机器部署。当然也可以部署在一台机器上,但是两个tomcat,jboss应用。
13 楼 peterwei 2011-04-24  
ppgunjack 写道
感觉DTO价值不在分层架构而在b-s间能大幅减少传输负载和浏览器端的内存损耗
如果是s测的分布式,价值大打折扣
如果DTO起抽象msg作用,那既不能替代别人也不应该被别人替代

其实我在为什么要用DTO那个章节上,已经说明了DTO存在的必要性,特别是在remote 访问的分布式应用时,几乎可以说是必需的。我也举了我们实际的例子说明。
其实用DTO模式做分布式的传输对象时,因为不是本机,是属于远程,所以缺点是网络延迟。但能减少不同层间的负载。
如web层只是action和页面(特别是静态化的页面),然后spring,dao等层做数据缓存。分开部署能减少对底层的连接压力。而且也能抽出核心应用层,供不同的异构的子系统调用(rmi或者hessian等协议)。
12 楼 joliny 2011-04-24  
如果大家有兴趣可以看看nec公司的sde架构。那才叫一个复杂。能见到的用的*O都用到了!!开发复杂度太高了。谁让人家不在乎钱呢。
11 楼 kimmking 2011-04-24  
虽然话题太老了。
但是说的还是在理,投个良。~
10 楼 hsiss 2011-04-24  
dto直接用map代替不就行了吗,为了架构而架构
9 楼 ltian 2011-04-24  
扫盲者没有说清楚DTO和PO的职责,其他人也没有说到点子上。
8 楼 jobar 2011-04-24  
ppgunjack 写道
感觉DTO价值不在分层架构而在b-s间能大幅减少传输负载和浏览器端的内存损耗


说的有道理,正是如此。。
7 楼 卡拉阿风 2011-04-24  
既然是用了hibernate,还有种替代dto的办法,使用select new map()..
6 楼 yangyiqian 2011-04-24  
首先我想说“存在就是真理”,DTO、PO绝对不是一个范畴的概念,DTO!=PO,所以也就谈不上谁代替谁的概念。当然了,你非要说老板就不能做员工的话吗?当然可以,不过这是做事的规矩吗?!

一、DTO与PO的不对称关系决定了二者不能互相代替
DTO与PO存在在映射关系,可能是多对一,也可能是一对多,最特殊的关系就是上面大家说的这种情况“一对一”。也就是在“一对一”的情况下可以实现DTO与PO的混用,而其他情况下,如果混用都需要PO进行冗余设计,考虑这些冗余设计会比直接的、简单的造一个新的DTO出现要耗费更多的脑细胞,同时这个东西又不利于后期维护,可以说“牵一发,动从上到下”。
二、性能上决定了PO代替DTO是个蹩脚的设计
PO是与数据库直接交互的对象,比如我要在页面上显示数据库中的数据,如果用PO来实现那么这个PO就得一直保持与数据库的连接,直到数据显示到页面上来。这样如果在service层有复杂运算的话,那么数据库方面的延时是非常可观的,而如果转换成DTO之后,数据库连接就可以尽快释放。所以从性能上来说应该使用DTO--当然对于性能不是很苛刻的情况下不用DTO也行 --不过,熟练的程序员应该养成按统一的方式做项目的习惯,我觉得这样会更高效。


5 楼 silence1214 2011-04-24  
个人也觉得DTO都低用不用还是根据实际情况来,有时候不需要分布,就是一个小应用,多余的DTO只会带来复杂度。你给的几个案例但是用着DTO蛮合适的。没有绝对的哈,知道有这么个架构思想,剩下来一切从需求出发吧
4 楼 skzr.org 2011-04-24  
<p>我做企业应用的,以前也听某某、某某谈论dto、vo、po甚至其他oo。<br>我认为最佳的实践:楼下两个基本上讲的是原则。</p>
<p> </p>
<p>
</p>
<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff; margin: 8px;">
<div class="quote_title" style="font-weight: bold; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; padding: 5px;">yangyiqian 写道</div>
<div class="quote_div" style="margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; background-color: #fafafa; padding: 3px; border: 1px solid #cccccc;">首先我想说“存在就是真理”,DTO、PO绝对不是一个范畴的概念,<span style="color: red;">DTO!=PO</span>,所以也就谈不上谁代替谁的概念。当然了,你非要说老板就不能做员工的话吗?当然可以,不过这是做事的规矩吗?!<br><br><strong>一、DTO与PO的不对称关系决定了二者不能互相代替</strong><br>DTO与PO存在在映射关系,可能是多对一,也可能是一对多,最特殊的关系就是上面大家说的这种情况“一对一”。也就是在“一对一”的情况下可以实现DTO与PO的混用,而其他情况下,如果混用都需要PO进行冗余设计,考虑这些冗余设计会比直接的、简单的造一个新的DTO出现要耗费更多的脑细胞,同时这个东西又不利于后期维护,可以说“牵一发,动从上到下”。<br><strong>二、性能上决定了PO代替DTO是个蹩脚的设计</strong><br>PO是与数据库直接交互的对象,比如我要在页面上显示数据库中的数据,如果用PO来实现那么这个PO就得一直保持与数据库的连接,直到数据显示到页面上来。这样如果在service层有复杂运算的话,那么数据库方面的延时是非常可观的,而如果转换成DTO之后,数据库连接就可以尽快释放。所以从性能上来说应该使用DTO--当然对于性能不是很苛刻的情况下不用DTO也行 --不过,熟练的程序员应该养成按统一的方式做项目的习惯,我觉得这样会更高效。<br><br><br>
</div>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">最佳实践:</p>
<p style="margin: 0px;">软件是发展的,我只认设计中的bean,如果bean要持久化就有po的职责了,一切都只是手段而已</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;"><span style="font-family: Arial, sans-serif, Helvetica, Tahoma; line-height: 18px;">难道是ORM把我们绑架了!太在意po和dto这样的概念了,设计才是根本,满足设计的bean才是核心。</span></p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">就正如时刻要记住的技术是为了实现业务需求而用,很多人反过来用了,为了技术而技术,被技术忽悠。最简单、是人就可以看懂的实现才是好实现</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;"> </p>
</div>
3 楼 lookdd1 2011-04-24  
开发网站就用网站的技术。。。别把JAVA EE的搞进来。你追不上那帮搞PHP的。。追不上那帮搞RAILS的。。。追不上就==死掉
2 楼 zym_nanako 2011-04-24  
如果web层和service层分离的话,那么service之间的调用是远程方式还是本地方式?
1 楼 ppgunjack 2011-04-23  
感觉DTO价值不在分层架构而在b-s间能大幅减少传输负载和浏览器端的内存损耗
如果是s测的分布式,价值大打折扣
如果DTO起抽象msg作用,那既不能替代别人也不应该被别人替代

相关推荐

    po vo dto bo to

    ### Java中的PO、VO、TO、BO、...PO、VO、TO、BO、DAO与POJO各自在系统架构的不同层次中扮演着不同的角色,相互之间既有联系又有区别。理解这些对象的概念及其应用场景,有助于我们在开发过程中做出更合适的设计选择。

    视图对象(VO、DTO)的应用!

    在软件开发中,视图对象(View Object,简称VO)和数据传输对象(Data Transfer Object,简称DTO)是两种常见的设计模式,它们在系统架构中起着至关重要的作用。这两种对象主要用于解决数据模型与界面展示之间的数据...

    DTO设计模式.docx

    DTO(Data Transfer Object)设计模式是一种在分布式系统中广泛使用的设计模式,它的主要目的是为了在系统组件之间传递数据。在大型应用程序中,特别是在服务层和表示层之间,DTO扮演着重要角色,因为它们能有效地...

    扩展MyBatisPlus代码生成器实现自定义源码生成,可生成前端页面、vo对象、dto对象等代码

    然而,对于VO对象、DTO对象以及前端Vue页面等非预置的代码生成需求,就需要我们对默认的代码生成器进行扩展和定制。 在MyBatisPlus 3.5.3版本中,代码生成器主要有两种类:`AutoGenerator`和`FastAutoGenerator`。`...

    java术语(PO/POJO/VO/BO/DAO/DTO)

    本文将详细解析"PO/POJO/VO/BO/DAO/DTO"这六个概念,并探讨它们在实际项目开发中的作用和应用场景。 1. PO(Persistent Object,持久化对象) PO是指与数据库表结构一一对应的Java对象,它通常包含了数据库表中的...

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    VO DTO 实体类的区别 java

    java简单基础 需要的了解一下 我们大家还是有必要去区分的

    VO / DTO / BO / ORM DAO entity DO PO/ POJO(分层领域模型规约)整理

    在现代软件开发中,特别是Java企业级应用开发中,为了更好地实现系统解耦、提高可维护性和可扩展性,经常采用分层领域的模型来组织代码。本文将详细介绍VO (View Object)、DTO (Data Transfer Object)、BO (Business...

    DDD分层架构参考代码目录结构

    在微服务架构中,DDD分层模型依然适用,但需要进行微调整以适应服务边界。每个微服务可以看作是一个独立的业务领域,拥有自己的用户接口层、应用层、领域层和基础层。微服务的一级目录结构通常按照DDD的四层模型划分...

    J2EE基础知识之DTO,VO,PO,DO等定义

    J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义

    快速生成DTO

    在软件开发过程中,数据传输对象(Data Transfer Object, DTO)是一种常见的设计模式,用于在系统之间传递大量数据。DTO不包含任何业务逻辑,主要是数据容器。在这个场景中,"快速生成DTO"指的是利用Excel模板来自动...

    分页dto把html写在dto里

    在IT行业中,DTO(Data Transfer Object)是一种设计模式,用于在系统之间传递数据,它将业务逻辑层与表现层的数据解耦。标题“分页dto把html写在dto里”和描述“把分页按钮写在dto里,其他dto继承他”表明了一个...

    DTO-code-generator:DTO设计模式的代码生成

    DTO设计模式已被广泛用于JavaEE项目中,尤其是在那些使用EJB,SOAP,REST等技术的项目中。讨厌编写DTO类并将这些值转换为Bean并反之亦然的开发人员。使用此API有一些简单的步骤,并将提到一些重要的注释。您所需要的...

    C#.net8创建webapi,使用SqlSugar,仓储模式,DTO,服务层,控制层的综合应用

    在本文中,我们将深入探讨如何使用C#.NET 8创建一个Web API,同时结合SqlSugar作为ORM工具,以及实现仓储模式、DTO(Data Transfer Object)转换、服务层和服务控制层的架构设计。这个综合应用旨在提供一个高效且可...

    J2EE设计模式的简洁总结

    DTO 模式或称 VO 模式,是指将数据封装成普通的 JavaBeans,在 J2EE 多个层次之间传输。DTO 类似信使,是同步系统中的 Message,该 JavaBeans 可以是一个数据模型 Model。 五、数据建模 数据建模是指将数据封装成 ...

    登陆的dto.zip

    DTO,全称Data Transfer Object,是软件设计模式中的一种,主要用在分布式系统或Web服务之间,用于数据的传输。DTO对象通常不包含任何业务逻辑,仅仅是数据的载体,使得不同层之间的数据交换变得简单。在这个"登陆的...

    Java设计模式 J2EE设计模式

    设计模式是经验丰富的开发者在实践中总结出的最佳实践,被广泛应用于J2EE多层系统架构中,包括架构设计、框架以及多种设计模式的组合。 GoF设计模式,即Gang of Four设计模式,由《设计模式:可复用面向对象软件的...

    JAVA中的POJO、VO、PO、DO、DTO都是什么?有什么区别?

    在Java开发中,我们经常会遇到各种各样的对象类型,这些对象有着特定的用途和命名约定。以下是关于POJO、VO、PO、DO、DTO...在实际开发中,根据项目需求和设计原则灵活选择和应用这些概念,能提高代码质量和可扩展性。

    POBOVODTOPOJODAO.zip_dto_java dto dao_java vo_qovod

    PO可以严格对应数据库表,一张表对映一个PO。... VO:value object值对象、view object视图对象 PO:持久对象 QO:查询对象 DAO:数据访问对象——同时还有DAO模式 DTO:数据传输对象——同时还有DTO模式

    J2EE设计模式.ppt

    DTO(Data Transfer Object)模式,又称为VO(Value Object)模式,主要用于在J2EE的多层架构间传输数据。DTO就像一个信使,将数据封装在普通的JavaBeans中,避免了直接传输数据库模型或业务对象带来的问题,特别是...

Global site tag (gtag.js) - Google Analytics