`
peterwei
  • 浏览: 249510 次
  • 性别: 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的。

欢迎拍砖,谢绝漫骂!
分享到:
评论
78 楼 抛出异常的爱 2011-04-27  
peterwei 写道

..........................

你说这种场合,用还是不用VO。工作量肯定是有的。如果不用VO,PO透传的话,可以省去一些类,Service层的代码也会简化很多。

至于查询方法,我也不必多说了,层级VO自然是有一大堆的转换。所以工作量还是有的。为了一些以后扩展,remote方式加入的情况,还可以接受这样的工作量。

Vo 继承 po 的方式可以达成你所说的目的.
只是比纯po的方式多了两三个空的类而已
77 楼 peterwei 2011-04-27  
抛出异常的爱 写道
peterwei 写道

................................

我想代码这东西你只要明白你想要什么
总会有办法解决的.

比如你的问题
set行数太多
到处重复

po到vo转换又不能省略的条件下


  class XpVO{
     .................
   //<-----上面是一般的vo代码--->
   //下面加一个构造器不就行了?
   public static XpVO createFromPo(XpPo,AccentPo){
   ...............
   }
   public static XpVO changeAccentFromPo(XpPo,AccentPo){
   ...............
   }
}


老抛说的肯定是要有的,我们封装了beanutils。但是即使封装了,别人还是觉得麻烦嘛。

你是想说你们的业务代码非常的简单只需要po就可以vo了?
那没问题
vo 继承  或 组合这些 po 就可以了....

PS:页面百分百不会与数据库一样的.
我作了多少项目没有一个项目不头痛这些
怎么也得有个可以加临时属性的地方.
嫌麻烦是好事
至少动过脑子

让他们把以前项目中的例子拿出来
写一个不带DTO的比较一下
看看会不会被恶心到...
想要去掉一些不合理的设计
非要狠狠动动脑子才可以......

多建少建个bean不算什么 工作量

多建几个对象不算什么工作量,但转换和保存,查询封装之类的就麻烦了。
我就举个一个实际项目的例子吧。确实会有不少工作量。
我们有三层对象,TransportTemplate对象,TransportTemplateDetail对象,底层CustomFreight对象,分别是1对多,再次1对多。

简单代码示例:
//第一层:
//基本属性略
private Set<TransportTemplateDetail> transportTemplateDetails = new HashSet<TransportTemplateDetail>();

//第二层:
//基本属性略
private TransportTemplate transportTemplate = new TransportTemplate();
private Set<CustomFreight> customFreights = new HashSet<CustomFreight>();

//第三层:略


那么你要建VO时,你得建三个层级结构差不多的对象吧。

某需求:批量保存参考界面,这个图是底层的自定义运费对象,点确定后要一下保存所有底层的东西。现在我们还没有说其它上层对象,如果要求上层对象的话,要涉及到dao层的三个层级对象。



我们先不说jsp页面到struts2 action的转换,这个肯定也是比较恶心人的。一般是json方式,action解析json,封装层次VO,传递到Service层,再对VO做属性的深度copy给PO,dao层最后保存PO。另一种是自定义类型绑定,我们现在是用这种方式。

我们来看一下Service层的某个批量保存add方法:
	public void addTemplateDetail(List<TransportTemplateDetailVO> transportTemplateDetailList) {
		TransportTemplate transportTemplate = new TransportTemplate();
		try {
			BeanUtils.copyProperties(transportTemplate, transportTemplateDetailList.get(0));
			for (int i = 0; i < transportTemplateDetailList.size(); i++) {
				TransportTemplateDetail transportTemplateDetail = new TransportTemplateDetail();
				BeanUtils.copyProperties(transportTemplateDetail, transportTemplateDetailList
						.get(i));
				transportTemplate
						.addTransportTemplateDetail(transportTemplateDetail);
			}
                           //如果是同一个界面,下面还有一层对象转换。我们分开两个界面来保存。这样还稍微简化了一些东西。
			transportTemplateDao.saveOrUpdate(transportTemplate);
		} catch (IllegalAccessException e) {
			throw new BusinessException("H10001", "转换模板VO失败");
		} catch (Exception e) {
			throw new BusinessException("H10002", "未知异常", e);
		}
	}


你说这种场合,用还是不用VO。工作量肯定是有的。如果不用VO,PO透传的话,可以省去一些类,Service层的代码也会简化很多。

至于查询方法,我也不必多说了,层级VO自然是有一大堆的转换。所以工作量还是有不少的。

为了一些以后的扩展,remote方式加入等情况,还是可以接受这样的工作量的。
76 楼 jayming 2011-04-27  
yimlin 写道
vo和po的区别就不多说了。

vo的作用有两种:
1.模块隔离:对外暴露,屏蔽内部实现。
2.分布式支持:用于异步传输;

换句话说:
如果不打算进行严格的模块化/组件化,又没有分布式场景,就不应该使用VO。
如果不打算进行严格的模块化/组件化,但存在部分分布式场景,比如lz所说的flex,那么针对部分进行VO开发即可;

此外,决定是否启用VO除了上述两个作用对应的场景外,另有如下两个因数:
1.PO是否是Rich Model?
2.开发人员是按分层分工还是按功能分工?

如果PO是贫血的,且是按分层分工开发的那么应该启用VO,因为,由于后台模型变化导致前台的调整会带来沟通协调的成本;
如果PO是Rich Model,且是按功能分工,那么就不应使用VO,VO和PO只会趋近,最终带来更多的维护成本,且在Rich Model下只变后台不变前台的比率较低,大部分情况下,功能的调整/改进会同时影响前后台。

同意之
75 楼 抛出异常的爱 2011-04-27  
service vo 如果是用来显示列表的话....
lazy的用法太恶心了.
有没有更好的方式?
74 楼 kusix 2011-04-27  
是否用VO,我觉着还是要看情况

如果架构是 dao-(po)->service-(vo)->action-(formbean)->page
那么VO实际上在formbean处还要做一道数据处理才能传到页面使用,因为VO并不能反映页面的所有情况。例如,如果一个页面上有多个块,我需要在一个request里暂时记录当前展示块的索引,这个就属于VO无能为力了,因为service依赖VO,而VO总不能依赖页面对吧。

目前我手头这个项目的三层架构是 service-(po)->action-(formbean)->page
直接把DAO和VO全部省略,为啥省略DAO那是另外的话题,只说VO,service层在处理PO时就把lazy这些问题处理了,action接到PO后把它裹在formbean中,再略做显示处理,直接往页面丢。

这样做的好处比较明显,值无需赋来赋去,开发快速,维护的代码少。同样缺点也比较明显,那就是由于PO和页面并不是能完全映射的,导致每次都会传输很多根本就不需要的数据到前台,这在list型页面中尤其明显。所以对于某些特定场景,例如list页面,考虑到网络传输效率,我们会使用VO,查询时就只查页面上需要的数据,再包装成VO传到前台。

所以是否使用VO,我的看法是,请在合适的场景使用它。

架构师要根据系统的实际业务场景权衡利弊来下决定, 如果干活的人普遍比较有素养,那么可以制定开发规范,来规定哪种场景必须使用VO,哪种可以用PO直传。如果对干活的人没信心,那就做好PO-VO转换的封装,麻烦就麻烦点,都用VO方式做。

总之,选择架构还是要根据合适的场景合适的人去确定合适的规则。
73 楼 JE帐号 2011-04-27  
哇,这个帖子还在扯啊.

DTO这个东西,缺点是啥,一个就是增加代码量,另外一个就是额外的值复制.
可是优点却有点太大了,使用DTO作为层与层数据交换的容器,可以完美的隔离层,无论是在协作开发,还是测试,以及功能修改方面,都有很多的好处.
虽然貌似增加了代码量,可是要知道这个代码的编写是质量及时间可控的,因为DTO很简单.而这点时间和精力消耗,相比他对代码的隔离而带来你修改功能的便利和寻找bug时范围的缩小还是很值的.

72 楼 抛出异常的爱 2011-04-27  
peterwei 写道

................................

我想代码这东西你只要明白你想要什么
总会有办法解决的.

比如你的问题
set行数太多
到处重复

po到vo转换又不能省略的条件下


  class XpVO{
     .................
   //<-----上面是一般的vo代码--->
   //下面加一个构造器不就行了?
   public static XpVO createFromPo(XpPo,AccentPo){
   ...............
   }
   public static XpVO changeAccentFromPo(XpPo,AccentPo){
   ...............
   }
}


老抛说的肯定是要有的,我们封装了beanutils。但是即使封装了,别人还是觉得麻烦嘛。

你是想说你们的业务代码非常的简单只需要po就可以vo了?
那没问题
vo 继承  或 组合这些 po 就可以了....

PS:页面百分百不会与数据库一样的.
我作了多少项目没有一个项目不头痛这些
怎么也得有个可以加临时属性的地方.
嫌麻烦是好事
至少动过脑子

让他们把以前项目中的例子拿出来
写一个不带DTO的比较一下
看看会不会被恶心到...
想要去掉一些不合理的设计
非要狠狠动动脑子才可以......

多建少建个bean不算什么 工作量
71 楼 peterwei 2011-04-27  
xurik 写道
vo po dto bean model actionform 等等 理不清 理还乱
这些问题 真要看实际情况了
就拿struts1和struts2 来说 已经有类似vo的概念了

没有什么理不清的,只要愿意花时间去理,一切都会慢慢清晰起来的。至于你说的struts1,struts2的类似vo的东西,虽说有点像vo(dto),但还不是,你还要再理一理,哈哈。
70 楼 xurik 2011-04-27  
vo po dto bean model actionform 等等 理不清 理还乱
这些问题 真要看实际情况了
就拿struts1和struts2 来说 已经有类似vo的概念了
69 楼 peterwei 2011-04-26  
抛出异常的爱 写道
peterwei 写道

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
}
}
}
}


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)放在防火墙内。



我想代码这东西你只要明白你想要什么
总会有办法解决的.

比如你的问题
set行数太多
到处重复

po到vo转换又不能省略的条件下


  class XpVO{
     .................
   //<-----上面是一般的vo代码--->
   //下面加一个构造器不就行了?
   public static XpVO createFromPo(XpPo,AccentPo){
   ...............
   }
   public static XpVO changeAccentFromPo(XpPo,AccentPo){
   ...............
   }
}


老抛说的肯定是要有的,我们封装了beanutils。但是即使封装了,别人还是觉得麻烦嘛。
68 楼 抛出异常的爱 2011-04-26  
peterwei 写道

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
}
}
}
}


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)放在防火墙内。



我想代码这东西你只要明白你想要什么
总会有办法解决的.

比如你的问题
set行数太多
到处重复

po到vo转换又不能省略的条件下


  class XpVO{
     .................
   //<-----上面是一般的vo代码--->
   //下面加一个构造器不就行了?
   public static XpVO createFromPo(XpPo,AccentPo){
   ...............
   }
   public static XpVO changeAccentFromPo(XpPo,AccentPo){
   ...............
   }
}

67 楼 peterwei 2011-04-26  
mercyblitz 写道
peterwei 写道
mercyblitz 写道
说正题,

这里我补充说明一下,Java EE Core pattern中都提到过了。

DTO就是TO(Transfer Object),传输对象,用于远程服务调用之间的信使。可能是单一的POJO,也可以是多个组合(主要减少网络传输TCP三次握手)。从生命周期而言,属于瞬时对象,只限于传输(调用之间)作为中间转换对象或者直接对象。

PO,也是实体对象(Entity Object),字面上理解,它要实实在在存在,那么需要持久化,有一定的生命周期。

VO,可以是TO,也可以是DO,作为POJO。这方面,楼主没有补充作为DO的地方。

DO你是指什么?Domain Object?我只是针对我们大多数项目用到的情况说的。DO我确实不大了解。如果是SDO倒有过粗略的了解。你可以补充呀。


DO = Domain Object呀,其实有时候分不清, Domain Object == Entity Object。所以,我为了不被概念混淆,主要分为两大类:Thin Object和Rich Object。

在不同的层次叫法不同,比如DAO中,Thin Object可以叫做PO,Entity Object。在表示层传输的话,就是DO或者VO。远程调用TO。 Rich Object主要用于重用点比较少的地方,因为毕竟Rich,很多耦合。


所以,看场景用不同的O蛋。

Rich现在还是少的。一般都是thin.所以我一般也就是说thin object.现在基本可以定论了。感谢各位同学的参与,鸣金收兵,开始干活。
66 楼 mercyblitz 2011-04-26  
peterwei 写道
mercyblitz 写道
说正题,

这里我补充说明一下,Java EE Core pattern中都提到过了。

DTO就是TO(Transfer Object),传输对象,用于远程服务调用之间的信使。可能是单一的POJO,也可以是多个组合(主要减少网络传输TCP三次握手)。从生命周期而言,属于瞬时对象,只限于传输(调用之间)作为中间转换对象或者直接对象。

PO,也是实体对象(Entity Object),字面上理解,它要实实在在存在,那么需要持久化,有一定的生命周期。

VO,可以是TO,也可以是DO,作为POJO。这方面,楼主没有补充作为DO的地方。

DO你是指什么?Domain Object?我只是针对我们大多数项目用到的情况说的。DO我确实不大了解。如果是SDO倒有过粗略的了解。你可以补充呀。


DO = Domain Object呀,其实有时候分不清, Domain Object == Entity Object。所以,我为了不被概念混淆,主要分为两大类:Thin Object和Rich Object。

在不同的层次叫法不同,比如DAO中,Thin Object可以叫做PO,Entity Object。在表示层传输的话,就是DO或者VO。远程调用TO。 Rich Object主要用于重用点比较少的地方,因为毕竟Rich,很多耦合。


所以,看场景用不同的O蛋。
65 楼 peterwei 2011-04-26  
mercyblitz 写道
说正题,

这里我补充说明一下,Java EE Core pattern中都提到过了。

DTO就是TO(Transfer Object),传输对象,用于远程服务调用之间的信使。可能是单一的POJO,也可以是多个组合(主要减少网络传输TCP三次握手)。从生命周期而言,属于瞬时对象,只限于传输(调用之间)作为中间转换对象或者直接对象。

PO,也是实体对象(Entity Object),字面上理解,它要实实在在存在,那么需要持久化,有一定的生命周期。

VO,可以是TO,也可以是DO,作为POJO。这方面,楼主没有补充作为DO的地方。

DO你是指什么?Domain Object?我只是针对我们大多数项目用到的情况说的。DO我确实不大了解。如果是SDO倒有过粗略的了解。你可以补充呀。
64 楼 mercyblitz 2011-04-26  
说正题,

这里我补充说明一下,Java EE Core pattern中都提到过了。

DTO就是TO(Transfer Object),传输对象,用于远程服务调用之间的信使。可能是单一的POJO,也可以是多个组合(主要减少网络传输TCP三次握手)。从生命周期而言,属于瞬时对象,只限于传输(调用之间)作为中间转换对象或者直接对象。

PO,也是实体对象(Entity Object),字面上理解,它要实实在在存在,那么需要持久化,有一定的生命周期。

VO,可以是TO,也可以是DO,作为POJO。这方面,楼主没有补充作为DO的地方。
63 楼 peterwei 2011-04-26  
mercyblitz 写道
peterwei,我警告你,不要和搞什么扫盲。搞这么多概念了出来,结果一群不明真相的同学又出来找你辩论,搞得老子看不出那个是SB了。

不少人连远程调用都不知道。


哈哈。不扫,以后找谁和我说话呢。现在那些大牛们又不来喷了。所以扫一批盲出来吧。哈哈,很多人确实不了解真相,你要说,他没看过一些相关资料,他们还真不明白。
62 楼 mercyblitz 2011-04-26  
peterwei,我警告你,不要和搞什么扫盲。搞这么多概念了出来,结果一群不明真相的同学又出来找你辩论,搞得老子看不出那个是SB了。

不少人连远程调用都不知道。

61 楼 peterwei 2011-04-26  
Cindy_Lee 写道
star022 写道
VO DTO POJO,都只是数据的封装而已,
如果每层交互都要做对象转换,重复代码多
除了增加研发和维护的人力成本,意义究竟有多大,值得思考!

我往往会找一些工具,或者自己扩展一些插件来完成这样的转换
比如 pojo对象转换成dto对象 我运用到了beanutils和注解形式自己写了个工具,转换也只是一行代码而已
User user = ......
UserDTO uDTO = MyBeanUtils.convert(user,UserDTO.class);
List<User> userList = .....
List<UserDTO> userDTOList = MyBeanUtils.convertList(userList,UserDTO.class);



这个肯定是必需的。但对于这样的转换,大家还是觉得有工作量。而且确实有工作量
60 楼 peterwei 2011-04-26  
pufan 写道
就问楼主一个问题:OO中的Object与layer之间有啥关系,这个啥关系都没有的道理如搞不清楚,扯那些po,dto,vo都是浮云,浮动在层上的云。

Object你又指的是什么?什么叫做和层没有关系?PO一般对应数据持久层的domain object,DTO(VO)对应大的封装过的domain object,一般用于特定场景,特别是服务层和界面(又以异构系统最常见)的接口数据。我们为了各层之间没有互相侵入性,隔离一些变化,所以有了分层解藕的概念,最终产生各层间传递对象的标准化。什么叫啥关系都没有的?你问就问得清晰些,我不想扯太多没用的。我认为我所说的还是很浅显的。不过你觉得是浮云,但我并不认为是这样的。了解不同场景下使用哪些东西,是很有必要的。不再多说了。
59 楼 Cindy_Lee 2011-04-26  
star022 写道
VO DTO POJO,都只是数据的封装而已,
如果每层交互都要做对象转换,重复代码多
除了增加研发和维护的人力成本,意义究竟有多大,值得思考!

我往往会找一些工具,或者自己扩展一些插件来完成这样的转换
比如 pojo对象转换成dto对象 我运用到了beanutils和注解形式自己写了个工具,转换也只是一行代码而已
User user = ......
UserDTO uDTO = MyBeanUtils.convert(user,UserDTO.class);
List<User> userList = .....
List<UserDTO> userDTOList = MyBeanUtils.convertList(userList,UserDTO.class);


相关推荐

    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