论坛首页 Java企业应用论坛

为什么我的程序传递DTO

浏览 41871 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-03-16  
关于Service层是传递DTO还是PO到表示层的争论,由来已久。但都没有定论。
现在,我要在传递DTO方式这边,加上一些砝码,使得天平倾斜过来。
传递DTO模式有以下优点:
1.DTO和DomainObject是不同视角下的产物,它们通过Assembler相互转换。这样,DTO和DomainObject就可以独立变化。DomainObject的内部结构变化不会影响表示层代码。
2.由于Service接口,依赖DTO来定义,所以Service接口,也不会因为DomainObject的变化而改变。进而,Service接口将不依赖DomainObject的lazy load。本来Service接口,就是对众多交互的抽象,这时候DomainModel还没成型呢。
2.由于DomainObject不会脱离Domain层存在,所以DomainObject当中可以包含需要安全控制的业务逻辑代码。

对于传递DTO模式,最大的批评,莫过于机械而无趣的Assembler代码。如果单从传递PO比传递DTO要少Assembler的观点看,似乎是正确的。但别忘了,直接传递PO,是以PO中不能包含需要安全控制的业务逻辑代码为代价的。为了存放这部分代码,业务控制对象产生了!这种没有状态的特殊对象,在传递DTO模式下,是不存在的。所有的DomainObject本即是业务控制对象,又是PO!
而且,因为业务控制对象同PO对象是分离的,也破坏了封装。
所以.....
   发表时间:2006-03-16  
我理解DomainObject最合适的角色,就是暴露给各层的领域对象,包括Business Entity(业务实体,比如Order/Product etc.)、Common Model(通用模型,比如TreeNode/ Pagination etc),等等。领域对象是程序员最不期望变化,但是也是实际需求中最容易变化的,特别是业务实体。

最常见的是表现层的变化,常常是需要修改 Business Entity的。对应于DTO模式就是,O(对应表现层数据结构)的变化,大多数情况会影响到D(对应持久层数据结构),反之亦然。

封装,只能隔离实现的细节。实际开发中,开发者和需求方对业务实体的认识有不断提高的过程。何不正视这点呢?业务实体的结构设计,应该作为各层开发人员的参考书,对业务实体都理解不透彻,还开发个P啊?

引用

但别忘了,直接传递PO,是以PO中不能包含需要安全控制的业务逻辑代码为代价的。为了存放这部分代码,业务控制对象产生了!这种没有状态的特殊对象,在传递DTO模式下,是不存在的。所有的DomainObject本即是业务控制对象,又是PO!


你这里指的仅仅是一种充血的模型而已。这里已经讨论太多了。
0 请登录后投票
   发表时间:2006-03-16  
sorphi 写道
我理解DomainObject最合适的角色,就是暴露给各层的领域对象,包括Business Entity(业务实体,比如Order/Product etc.)、Common Model(通用模型,比如TreeNode/ Pagination etc),等等。领域对象是程序员最不期望变化,但是也是实际需求中最容易变化的,特别是业务实体。

最常见的是表现层的变化,常常是需要修改 Business Entity的。对应于DTO模式就是,O(对应表现层数据结构)的变化,大多数情况会影响到D(对应持久层数据结构),反之亦然。

封装,只能隔离实现的细节。实际开发中,开发者和需求方对业务实体的认识有不断提高的过程。何不正视这点呢?业务实体的结构设计,应该作为各层开发人员的参考书,对业务实体都理解不透彻,还开发个P啊?

引用

但别忘了,直接传递PO,是以PO中不能包含需要安全控制的业务逻辑代码为代价的。为了存放这部分代码,业务控制对象产生了!这种没有状态的特殊对象,在传递DTO模式下,是不存在的。所有的DomainObject本即是业务控制对象,又是PO!


你这里指的仅仅是一种充血的模型而已。这里已经讨论太多了。

这不是RoR吗?基于Naked Object结构的RoR,Naked Object能够满世界跑。所以如果在JAVA里面要做到彻底暴露,就不需要Hibernate这样的ORM,直接将PO同数据库的记录1-1对应就好了。难道ORM不是另一个“烦人的”转换?
如果,你认为将行为同其操作的数据封装在一起没有意义,那么,甚至还可以将数据作得更简单。利用通用的类似CachedRowSet的通用容器,甚至可以不需要写一行PO的代码。或者可以使用EMF实现的SDO同样可以用一致的方式,来访问数据,并且不管数据如何变化,结构总是稳定的。
扯远一点,在竞争中,东芝公司不得不放弃,其开发的SmartMediaCard.一个很重要的原因就是SmartMediaCard,不包含读取数据的部件?!(节约成本?)使用的也是Naked Data,这导致,不同厂家在读取数据时,需要自己处理,往往造成读不出数据,或者只能读出特定容量的卡。相反其他如SD卡,就聪明得多,如何读取数据由卡本身来负责,使用卡的厂家,只需要知道读写接口就是了。

RichDomainModel虽然讨论得不少,但是,我不认为有多少有用方案和值得赞赏的见解,实际上,我认为这里大多关于RichDomainModel的讨论大多流于形式,实质的东西,没有看到。所以,我认为有必要在这个问题上,发力......
0 请登录后投票
   发表时间:2006-03-16  
引用
DTO和DomainObject就可以独立变化

要能够独立变化,一是两者本质上毫无关系;二是两者间独立于抽象化的概念,这个抽象化概念可以是人为建立的.
DTO和DomainObject的独立性只能建立在人为给予的抽象概念.
如DomainObject的属性变化,需要DTO来传递这种变化,那么丧失了独立性,因为这时候已经不是在抽象概念的层面上.
本人看引入DTO,代价高于其带来的独立性所带来的效益
0 请登录后投票
   发表时间:2006-03-17  
我看PO和DTO独立变化只是增加了复杂性,引入了另一套对象模型,以及同步的代价.
引用
对于传递DTO模式,最大的批评,莫过于机械而无趣的Assembler代码

如果DTO和PO一对一的话,这步就可以通过某种代码生成机制由metadata生成,反正VO里又没有别的逻辑,生成后不用手动改.
0 请登录后投票
   发表时间:2006-03-17  
nihongye 写道
引用
DTO和DomainObject就可以独立变化

要能够独立变化,一是两者本质上毫无关系;二是两者间独立于抽象化的概念,这个抽象化概念可以是人为建立的.
DTO和DomainObject的独立性只能建立在人为给予的抽象概念.
如DomainObject的属性变化,需要DTO来传递这种变化,那么丧失了独立性,因为这时候已经不是在抽象概念的层面上.
本人看引入DTO,代价高于其带来的独立性所带来的效益

DTO同DomainObject能独立变化,是说,它们变化的原因不同,一个是基于交互逻辑的抽象,一个是基于对业务逻辑的抽象。 不同的原因产生相同的变化要求,很正常。但是不同的原因也会导致不同的变化要求。例如:在显示员工列表时,交互逻辑关心的属性有“员工姓名”、“员工编码”、“部门名称”、“部门编码”。最初的Domain结构,我可以这样设计。Employee--->Department,后来,业务逻辑发现需要关心Employee所属岗位,Domain结构变为Employee--->Post---->Department。如果交互逻辑直接耦合PO,那么,这部分组装代码你需要改变。
我认为,对交互逻辑的抽象,同对业务逻辑本身的抽象,是两个完全不同的意图。直接传递PO,就混合了这两种意图。表示层直接耦合业务层,使得夹在它们之间的Service层,几乎变得毫无意义。表示层接受PO,是否意味着,表示层可以修改PO?PO可以在表示层修改,那么Domain层还有多少意义?我是否可以把PO在表示层完全修改好,然后传递回后台,后台只负责简单的持久化,不就完了?业务对象(BO)有必须存在的理由吗?

引入DTO带来的利益,难道还不足以抵消,对于增加一个DTO和一个Assembler的开销?
DomainModel能够完全的OO! 就凭这一点,我认为就够了。使用XXXManager、XXX对的方式处理,你看起来就那么舒服?还是那句话,这样还不如去直接操作集合数据呢!DomainObject的业务逻辑,就该满足其本身的结构,让DomainObject去驱动DomainObject是最自然的想法。如果采用XXXManager的方式,因为可以操作任何它想操作的PO,实际上,就违反这种驱动模式,仿佛是四维空间的一只手,操作着三维空间的物体,可以不按三维的规则出牌,会导致,DomainObject状态不一致,或不完备。

不能忍受DTO,确可以忍受操作和数据分离的DomainModel。这对我来说,是不可理解的。
0 请登录后投票
   发表时间:2006-03-17  
towjzhou 写道
我看PO和DTO独立变化只是增加了复杂性,引入了另一套对象模型,以及同步的代价.
引用
对于传递DTO模式,最大的批评,莫过于机械而无趣的Assembler代码

如果DTO和PO一对一的话,这步就可以通过某种代码生成机制由metadata生成,反正VO里又没有别的逻辑,生成后不用手动改.

问题就在于你的这种假设是否站得住脚?
0 请登录后投票
   发表时间:2006-03-17  
partech能不能给个具体一点的例子?
0 请登录后投票
   发表时间:2006-03-17  
DTO,或者VO,存在的理由是业务人员看到的业务领域视图,和开发人员看到的是有区别的。
不同的视图差异,就需要我们做不同的处理,就像我们处理对象和数据库一样。

不过写太多的assembler代码也很郁闷的,希望有一种类似hibernate的东西来处理,尝试中。
0 请登录后投票
   发表时间:2006-03-17  
Archie 写道
partech能不能给个具体一点的例子?

例子当然需要提供,不过要配合我们项目的节奏,给点时间我。
0 请登录后投票
论坛首页 Java企业应用版

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