论坛首页 Java企业应用论坛

讨论:多层架构中是不是绝对不能把PO传递到表现层?

浏览 125736 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-05-21  
大家都知道,PO是不被提倡直接送到表现层的,因为这样做
1.不能降低层次间的耦合度,不利于以后的维护。
2.在lazyloading的时候可能还取不到数据。

所以通常我们的做法是这样的:
PO1 = session1.load();;
DTO = beanUtils.copyProperties(PO);;
client.displayAndModify(DTO);;
PO2 = session2.load();;
PO2 = beanUtils.copyProperties(DTO);;
session2.save(PO2);;


但是,按照我目前的粗浅了解,不把PO传递到表现层也并不是绝对的。当一个PO没有用lazyloading的时候,把它作为一个detached object送到表现层也不失为一种优雅的解决办法,否则hibernate也没有必要提供update和saveOrUpdate方法了。

PO = session1.load();;
client.displayAndModify(PO);;
session2.saveOrUpdate(PO);;


两段code比较起来,第二段要简单明白许多。

所以,我的结论是,可以有限度的把PO传递到表现层,而不是绝对的要怎么样怎么样。

请大家有砖砸砖,有水灌水。
   发表时间:2004-05-21  
xanada 写道
大家都知道,PO是不被提倡直接送到表现层的,因为这样做
1.不能降低层次间的耦合度,不利于以后的维护。
2.在lazyloading的时候可能还取不到数据。

所以通常我们的做法是这样的:
PO1 = session1.load();;
DTO = beanUtils.copyProperties(PO);;
client.displayAndModify(DTO);;
PO2 = session2.load();;
PO2 = beanUtils.copyProperties(DTO);;
session.save();;


但是,按照我目前的粗浅了解,不把PO传递到表现层也并不是绝对的。当一个PO没有用lazyloading的时候,把它作为一个detached object送到表现层也不失为一种优雅的解决办法,否则hibernate也没有必要提供update和saveOrUpdate方法了。

PO = session1.load();;
client.displayAndModify(PO);;
session2.saveOrUpdate(PO);;


两段code比较起来,第二段要简单明白许多。

所以,我的结论是,可以有限度的把PO传递到表现层,而不是绝对的要怎么样怎么样。

请大家有砖砸砖,有水灌水。


这个问题我也想过,目前的做法是:
如果不写入,只是显示,不管怎样都直接传递po到表示层,
如果表示层需要写对象,就传递po.clone()-这里我让po实现clone的接口,
而不再创建dto对象。

那个lazyloading的问题,我会在action层,强迫其初始化。
所以class的lazyloading对我来说没有什么意义,我也觉得一般极少
load了而不使用。真正有用的collection的lazyloading。

继续砸砖。。。
0 请登录后投票
   发表时间:2004-05-21  
我是把PO传递到显示层的,不使用DTO,减少不必要的麻烦。

http://www.hibernate.org/hib_docs/online/atljug04_presentation/hibernate_atljug2004.pdf
里面有提到 DTOs are Evil 和 Detached Object Support

Lazyload的问题可以通过open session in view解决,或者准备好完整的数据以后才交给显示层展现。
1 请登录后投票
   发表时间:2004-05-24  
看到这样的问题楼上的几位兄弟还在讨论,实在有些遗憾。我曾经在关于这样问题讨论上发了多个帖子,可惜,大家都不怎么看,看了也不怎么思考。
   PO是什么?难道就是hibernate中间才有?如果是讨论具体的一样东西,我也须不会回帖了,但是看到大家把架构都抬出来,但是一些基本的概念都不清晰的时候,我想我应该回帖的。
   没有hibernate是否有PO?当然!CMP、BMP、JDO都是PO,甚至你自己都可以写一个,只要这个对象具有持久性,就是PO。我想问问楼上几位,CMP、BMP可以传递到表现层么?
   你们所谓的传递到表现层的对象已经不是PO,而是VO了,因为它根本不具备任何持久性,只是一些数据的对象封装罢了。VO又是什么?它和PO有什么关系?PO反映的是数据库实体的存储,而VO是反映的是业务逻辑或者表现逻辑的一种对象(或者又称为DTO吧)。一个VO可以小于一个PO(比如说我们查询的列表,就只会显示少许的字段);一个VO可以大于一个PO(简单地将,就是一个数据库视图级的反映);一个VO可以完全和一个PO相同(也就是楼上出现的现象了)。
    如果自己实现PO,那么的话,我们的确可以用一个对象起PO和VO的双层作用,但是我可以说,这是极其低劣的设计。为什么?简单地讲,它给我们带来这样几个问题:一、所有的表现与数据库的存储完全挂钩,既然这样,就不要谈什么架构了,谈架构就是笑话。二、系统间完全耦合,没有任何层次可言,任何一个地方的修改会导致整个系统的修改。三、当需要一个VO大于PO的情况(我们知道数据库许多表中存储的是相应其他表的外键,而不是具体的值),这个时候,就会出现数据装载的问题(要么采用延迟装载,要么一次性大装载),极端地讲,一个业务实体如果引用了十多个基础实体,那么在显示业务实体的时候,就必须访问十多次数据库,要么就是一次性十几个实体全部装载,两者就是速度、内存的极端反映。
   说了这么多,我希望楼上的兄弟在讨论架构这样大型的概念的时候,要充分地想一想。批判精神要有,但是前提是你真得理解了~~~~~~~
   希望这样的帖子,对你们有益~~~~~~。
0 请登录后投票
   发表时间:2004-05-24  
关键是楼主没有做过这方面的项目,如果在项目中采用“PO传递到表现层”就会吃到苦头。
我已经吃过这方面的苦了。
0 请登录后投票
   发表时间:2004-05-24  
我就是怕吃苦頭﹐所以就統一的把po在action層轉換成vo,我現在用的是struts+hibernate﹐所以一直注意這方面的東西﹐也開貼討論過﹐但是大家好象道理說了一大堆﹐但是沒有把具體的東西分享出來﹐我很不想看到有人說﹐具體問題具體對待﹐個人有個人的情況﹐那么能不能把你個人的情況說出來﹐在hibernate問題解答版﹐我發了一個關于struts+hibernate的架構設計﹐被斑竹加為精華﹐現在看來﹐真的汗顏。。。﹐寫的很爛﹐真的希望不會誤導大家。
0 请登录后投票
   发表时间:2004-05-25  
引用
   PO是什么?难道就是hibernate中间才有?如果是讨论具体的一样东西,我也须不会回帖了,但是看到大家把架构都抬出来,但是一些基本的概念都不清晰的时候,我想我应该回帖的。
   没有hibernate是否有PO?当然!CMP、BMP、JDO都是PO,甚至你自己都可以写一个,只要这个对象具有持久性,就是PO。我想问问楼上几位,CMP、BMP可以传递到表现层么?
   你们所谓的传递到表现层的对象已经不是PO,而是VO了,因为它根本不具备任何持久性,只是一些数据的对象封装罢了。VO又是什么?它和PO有什么关系?PO反映的是数据库实体的存储,而VO是反映的是业务逻辑或者表现逻辑的一种对象(或者又称为DTO吧)。一个VO可以小于一个PO(比如说我们查询的列表,就只会显示少许的字段);一个VO可以大于一个PO(简单地将,就是一个数据库视图级的反映);一个VO可以完全和一个PO相同(也就是楼上出现的现象了)。
    如果自己实现PO,那么的话,我们的确可以用一个对象起PO和VO的双层作用,但是我可以说,这是极其低劣的设计。为什么?简单地讲,它给我们带来这样几个问题:一、所有的表现与数据库的存储完全挂钩,既然这样,就不要谈什么架构了,谈架构就是笑话。二、系统间完全耦合,没有任何层次可言,任何一个地方的修改会导致整个系统的修改。三、当需要一个VO大于PO的情况(我们知道数据库许多表中存储的是相应其他表的外键,而不是具体的值),这个时候,就会出现数据装载的问题(要么采用延迟装载,要么一次性大装载),极端地讲,一个业务实体如果引用了十多个基础实体,那么在显示业务实体的时候,就必须访问十多次数据库,要么就是一次性十几个实体全部装载,两者就是速度、内存的极端反映。


PO ,persistence object,
VO,value object
dto,data transfer object
bo,business object

好多的名词啊,晕!

我们开始也是这样做的,拿到hibernate的po,就一股脑的扔给view(jsp)显示去

了,不好,俺知道,确实不好。

后来,俺们这样做了:用beanutil把po的各个属性值拷贝给了FormBean,让formb

ean去跟view打交道。

再后来,俺们觉得,action不应该直接就调用dao,俺们加了一个BusinessFacade
action---->facade--->dao
action把formbean的值转到po,然后交给facade,facade再调用dao

再后来,俺们觉得,还是martinFlower的domain

model更酷一些,俺们就把buinessFacade重构成了一个Biz对象,他是一个业务实

体,他有着和po差不多该有的属性,用来存放业务值,但是他也有着同样的各种

业务方法,他已经不再是一个facade了,而是一个facade+PO了,我们叫他真正的

业务对象。他有几个职责:接受web层数据;加工数据;持续化数据(不是自己做

,是调用dao).

你们看,多么曲折的系统重构历程啊,可是,就是这样,俺们仍然感到很多很多

的不足,因为,这个Biz对象,还是只能代表一个对象,而不太好表现一个对象图

(就是他和别的对象的关系),太抽象,是吧?

举个例子吧:

俺们有一个账户业务对象:AccountBiz

他有一些属性:
String guid;
String name;
String password;


他还有一些方法:
findHisRoles();;
load();;


我在action中,这样调用他
biz = new AccountBiz("guid");;
biz.load();;
List roles = biz.findHisRoles();;


你看,他找到了他的所拥有的所有角色,可是,你想想,roles里面是什么?理想的是:RoleBiz,你知道的,业务层,应该看到的都是业务层的对象,可是呢,实际上,这个方法的实现是:
public List findHisRoles();{
  return dao.findHisRoles(this.getGuid(););;
}
看看,实际上,返回的是一堆AccountPO的实例,我是不是应该把这些PO,一个个的都转化成Biz呢,我们现在没有做,看来是应该做的。

但是,如此做的话,实际上,你的业务层的对象看来就真的变成了,hibernate还原出来的对象图+这个业务实体的业务方法。

嗯,这就是俺们的结论,这样实现固然很好,看上去很美,但是,对于中小项目而言,使用po直接的贯穿始终,俺们觉得也挺好的。

嗯,跟贴吧,拍砖吧
0 请登录后投票
   发表时间:2004-05-25  
To: 凤舞凰扬

其实我想讨论的是:多层架构中是不是绝对不能把PO传递到表现层?举一个最简单的例子,一个VO可以完全和一个PO相同。这种情况下,又为什么不能把PO传递到表现层呢?所以说,批判精神要有,但是前提是你真得理解了别人在讲什么~~~~~~~

那么有人又会说,这是极其低劣的设计,因为架构,耦合blablabla,其实这才是我想要说的:不要为架构而架构,为耦合而耦合,你真的明白你需要的是什么吗?你知道什么是YAGNI principle吗?面对一个概念清晰,层次臃肿的架构和一个实现优雅,层次简单的架构,你会选择哪个?

我会毫不犹豫的选择后者,而非前者。
0 请登录后投票
   发表时间:2004-05-26  
一个VO和PO相同,这当然可以,但是这并不意味着PO可以传到表现层,因为那根本就不叫PO了(我前面的帖子已经很明显地说了,你所谓的PO起了两个作用). 首先,我们明确我们是讨论什么问题,是问在实际中一个对象是否可以在各个层次生存还是问在架构设计中这样做是否恰当? 如果,楼上只是谈一个对象是否可以在表现层、业务层、持久层都存在,当然是可以的,但是如果把它拿到概念层次,谈所谓的架构和框架,就不能这么说了。我不知道楼上是否懂了!
    如果楼上讨论架构,把问题说这么大,我可以这么说,让一个对象从头到尾的使用100%是低劣的设计。我另外想说的是,低劣地设计并不是完成不了功能,只是它没有好的可维护性和可扩展性。
    如果只是单纯解决某个问题,当然可以像楼上那么做,要知道,在必要的时候,连GOTO都可以,但是我们不能因此说明这样的设计是好的吧?楼上,你在考虑问题的时候,只是贪图某些局部的便利性,追求某种所谓的简洁,要知道,要真是所谓的简洁,就不需要架构设计师去思考设计架构了!
1 请登录后投票
   发表时间:2004-05-26  
我们在这里谈的绝对不是说一件事情绝对能怎么样或者不能怎么样,那样没有意义,不是么?比如说,我们强烈建议在程序的编码中不要使用goto,但是同样不意味着绝对,为什么?因为在很多领域(比如数值分析,图形绘制)都离不开它,并不是像有些人所谓的goto可以被三种基本过程(顺序,分支,循环)所代替就真能所代替的。
    我只所以发这些帖子,不是针对任何一个人,但是我可以说,我是过来人,在我经历的最开始的时候,在使用petstore的架构的时候,我就碰到了诸多问题。经验是积累的,我愿意把我所积累的一些东西与大家共享,也愿意分享大家的经验,各自都少走弯路。
    楼上你可以发起投票,我相信有三到五年以上经验100%是同意我的说法的,原因其实很简单。
    一个好的程序员,个人的理解能力很重要,但是更加重要的是吸收。也许我的语气让你感到了排斥感,这倒没有什么,只是不希望你再走这样的弯路
2 请登录后投票
论坛首页 Java企业应用版

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