论坛首页 Java企业应用论坛

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

浏览 42546 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-04-27  
vo po dto bean model actionform 等等 理不清 理还乱
这些问题 真要看实际情况了
就拿struts1和struts2 来说 已经有类似vo的概念了
0 请登录后投票
   发表时间:2011-04-27   最后修改:2011-04-27
xurik 写道
vo po dto bean model actionform 等等 理不清 理还乱
这些问题 真要看实际情况了
就拿struts1和struts2 来说 已经有类似vo的概念了

没有什么理不清的,只要愿意花时间去理,一切都会慢慢清晰起来的。至于你说的struts1,struts2的类似vo的东西,虽说有点像vo(dto),但还不是,你还要再理一理,哈哈。
0 请登录后投票
   发表时间: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不算什么 工作量
0 请登录后投票
   发表时间:2011-04-27  
哇,这个帖子还在扯啊.

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

0 请登录后投票
   发表时间: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方式做。

总之,选择架构还是要根据合适的场景合适的人去确定合适的规则。
0 请登录后投票
   发表时间:2011-04-27   最后修改:2011-04-27
service vo 如果是用来显示列表的话....
lazy的用法太恶心了.
有没有更好的方式?
0 请登录后投票
   发表时间: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下只变后台不变前台的比率较低,大部分情况下,功能的调整/改进会同时影响前后台。

同意之
0 请登录后投票
   发表时间:2011-04-27   最后修改: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方式加入等情况,还是可以接受这样的工作量的。
  • 大小: 62.8 KB
0 请登录后投票
   发表时间:2011-04-27   最后修改:2011-04-27
peterwei 写道

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

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

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

Vo 继承 po 的方式可以达成你所说的目的.
只是比纯po的方式多了两三个空的类而已
0 请登录后投票
   发表时间:2011-04-27  
引用
Vo 继承 po 的方式可以达成你所说的目的.

但是这样,会不会各层绑定得太紧?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics