关于VO与PO的问题

08-08-19 yongbuyanbai
看了许多关于VO与PO的讨论,VO是针对表示层显示数据的载体,而PO相当在后台业务逻辑中传递的数据BEAN的载体,在控制层将VO转换为PO,常常利用apache commons的BEANUTILS,如果在项目中有如下VO和PO

   class PO
   {
     private UserPo;
   }
 class VO
   {
     private UserVo;
   }

<p>

对于这种情况,利用beanutils的方式需要类型匹配,而userpo与uservo是不匹配的肯定报错,所以这种情况就很烦琐,不知道如何解决,请banq指导!而且对于VO的使用是否是必要的也予以怀疑,直接用PO在层间传递是否可以呢?

2
freebox
2008-08-19 17:10
UserPo和UserVo复杂了吧?实在需要就让它俩都实现相同的接口。

yongbuyanbai
2008-08-19 23:46
如果不用VO是否妥当,我看有的人说直接就用PO在各层传输就可以!各有各的说法,但是这种方式好象是加强了耦合,但是如果有VO又太复杂,到底应该如何处理呢?

freebox
2008-08-20 08:16
我是看这俩对象的状态是不是和领域对象一至,一至的话就都用领域对象来表达,不一至比如说VO是由多个领域对象组合成的,就另弄一个。

yongbuyanbai
2008-08-20 09:44
在我这个项目中基本是一样的,如果按照您说的混合了多个领域对象的话,便会产生这样一个混合的VO然后在控制层将其组装成多个领域对象向下传,然后将获得的多个数据载体的PO传递给VO,在页面显示,那么不同字段如何进行拷贝,用APACHE BEANUTILS的只能是类型相同的,所以拷贝很烦琐,不知道有什么好的工具类可以应用这个方面!我记得BANQ好象说过将PO与VO尽量的一致起来,这样的传输是没有交叉的不复杂,直线传输,很清晰!请谈谈您的观点,如果BANQ看见了也请把您的想法讲讲,谢谢了哦!

freebox
2008-08-20 17:41
上帖两个错字,一致的致写成“至”了,改不了了。

我觉得不能以是不是一致为标准,应该是需要这个对象就是这个对象,显示的时候需要组合就要组合,不能是为了达到一致让本来应该组合而成的对象变成一个对象,那这个大对象没有业务意义。

复制的复杂性的确存在,我一般在service里完成,到了domain里都是业务对象,不会有那种组合成的大对象。

yongbuyanbai
2008-08-21 09:11
恩,很受启发,还有个疑问,你说的把VO向PO的转换放在service妥当吗?我一般对不复杂的是放在控制层里写,比如action中,然后传递给service的是业务对象,而不是VO!不知道这两种哪个更妥当些,从分层耦合的角度考虑,请解释下!

banq
2008-08-21 10:07
我以前说过,不要有那么多O,都是打着Object名义,尽干些鸡鸣狗盗的事情。

就说这VO,实则是贫血模型,来自过去数据库时代,表示是数据封装起来的一个对象,他和Evans DDD中值对象是有区别的。

PO更是容易引起歧义。PO和业务对象什么关系呢?

其实了解了Evans DDD以后,PO更象实体 而值对象是从属于实体的,但是传统概念VO和PO是平级的,你还要互相拷贝呢,所以,概念太多不好,统一到DDD的实体和值对象上来。

在MDD模型驱动开发下,先有领域模型,而界面模型是领域模型在界面上的体现,在JSF/Struts2中,都是直接将领域模型作为界面模型,这样你就没有什么拷贝之说,但是这点是有风险的,因为界面对象到底和领域模型是有些区别的,因为界面对象中有一些直接和界面显示有关,如果两者合一,将界面显示相关的字段写到领域模型,这就破坏领域模型的高度性和纯洁性。

所以,我赞成界面对象和领域对象分开,也就有拷贝,从设计上看,因为界面对象大部分和领域对象字段一致,取相同的set/get名称就可以,至于字段不一致,拷贝工具不会拷贝的,也就不会出错,只拷贝相同set/getXXX名称,出错可能是你set/get两个方法没有全部出现,只有一个get/set

猜你喜欢