论坛首页 Java企业应用论坛

再乱弹一下“领域模型与数据访问接口的依赖问题”

浏览 22636 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-09-13  
记得前些时候,我在javaeye发了一个帖子,引发了一段争论,具体的请看这个链接:
http://forum.iteye.com/viewtopic.php?t=11712

可以说Robbin是用心思考后才作出这个总结的,这个总结很有意思,也很有道理。但是并不能说全对,说实在话,我对于技术的观点一直是反反复复的,这个反复是随着我对技术的一种体会而来,可能先对后错,也可能先错后对,但是无论怎么反复最终的观点我个人认为还是无限接近于正确的。    
先撇开Marin fowler的观点不说,因为引入他的结论无异于导致另外一种争论。
Robbin一直坚持这么一种观点:领域模型依赖于DAO接口是很evil的。
可以说这种观点不是很正确的,正如Rod Johson说的一样,这个依赖的划分应该基于重用性来进行划分。正如领域模型依赖于DAO似乎是一道很难逾越的门槛一样,逾越了这道门槛会带来很多东西。也可以将领域模型带入一个高度:即更加OO的一个高度。

然而,逾越这个门槛会带来一些问题,首先一点是单元测试的问题,DAO是很薄的一层接口,单元测试可以MOCK或者建立有效的测试步骤来解决。
另外一点就是跟现在ORM流行的实体数据类有一种微妙的冲突,HIbenate以及JDO,甚至到现在的EJB3 data persistence ,都给实体无形中框定了一个套子:数据+ 紧密依赖此对象状态的业务逻辑。

这个套子本没什么错,但是我觉得还是一个限定了OO的套子,紧密依赖此对象状态的限定,意味着它要比考量可复用的业务逻辑还要严格很多。 也就暗示着这么一个结论:领域模型不应该依赖于DAO接口。这点在EJB3的callBacks体现无疑。 很遗憾,他们给出了太多或许错误的设计方法以及设计规范。因为他们设计的系统的缺陷而无情把可复用的OO精髓扼杀在了产品规范上。

说道OO,我觉得我很有必要说我对OO的观点,不谈那些流行的设计模式,只谈一点,我认为最核心的一点:
真正的OO设计应该是类似事件传播的一种机制,而不是一种ActionScript/过程编写的手法。这点在Martin fowler 的企业设计模式里提到, 虽然仅仅一小章节提到这个观点,但是无疑这句话道出OO精髓,附件中给出简单的示意图。

道理确实太简单,估计很多人会不屑,但是我反倒觉得这个道理因为太简单而导致其意义最深邃.        
关于OO我仅提这么多。下面接着上面的正题。

一个合理的领域模型框架可以是这样:

                    Account---------------->DAO---------------->DB.

到具体的应用开发的时候,结合应用逻辑可以那么就是这样:
Facade--->App Logic--><Domain model>-->DAO-->DB
                
                App Logic
                   |
                    _-----------------DAO-->DB

    
在Application Logic这一层来定义事务边界。
我认为:基于是否依赖于数据持久层来决定业务 逻辑是否应该放在Domain model中这个说法,无论如何都是一种近乎苛刻的限制,而且这种说法也会最终导致Domain Model不得不在其上再套上一层所谓的Domain Model Manager层,这层才是真正存放大部分的业务逻辑。 最终导致这一层形成类似的Action script开发的方式。也最终限制了OO在业务领域模型的设计。
   发表时间:2005-09-13  
同感。
0 请登录后投票
   发表时间:2005-09-14  
这么长时间都在想啥呢?
从业务建模的角度来看,业务对象的持久化完全不在考虑范围之内。可以认为业务对象就已经在那里了,不用考虑如何创建,查找等等机制。重点是考虑业务对象和他们之间的静态结构和动态关系。如果说业务逻辑是指在业务上包含的逻辑,那么业务逻辑就包含在业务对象中,而持久化就不能算是业务逻辑,它不过是一种实现机制而已,同客户理解的业务逻辑有明显区别。正是因为他们有很明确的区别,所以可以将它们分离开来。应用逻辑,我认为它仅仅起桥梁作用,用来沟通(转换)交互逻辑和业务逻辑。实际上,持久化可以认为是一个扩展的Aspect,它依赖于业务对象。事务属于持久化的范畴,完整的持久化Aspect应当包含它。
0 请登录后投票
   发表时间:2005-09-14  
引用
从业务建模的角度来看,业务对象的持久化完全不在考虑范围之内。可以认为业务对象就已经在那里了,不用考虑如何创建,查找等等机制。重点是考虑业务对象和他们之间的静态结构和动态关系。如果说业务逻辑是指在业务上包含的逻辑,那么业务逻辑就包含在业务对象中,而持久化就不能算是业务逻辑,它不过是一种实现机制而已,同客户理解的业务逻辑有明显区别。正是因为他们有很明确的区别,所以可以将它们分离开来。应用逻辑,我认为它仅仅起桥梁作用,用来沟通(转换)交互逻辑和业务逻辑。实际上,持久化可以认为是一个扩展的Aspect,它依赖于业务对象。

    理论上讲是成立的,但在和现在的O/R映射工具很难结合起来,因为HIBERNATE等工具的"工作单元"实现大部分是"工作单元控制器"方式而非调用者注册或者领域模型注册的方式.请教firebody,JDO是否也是这样?
引用
事务属于持久化的范畴,完整的持久化Aspect应当包含它。

    事务不属于持久化的范畴,好像讨论过多次了
0 请登录后投票
   发表时间:2005-09-14  
firebody 写道
记得前些时候,我在javaeye发了一个帖子,引发了一段争论,具体的请看这个链接:
http://forum.iteye.com/viewtopic.php?t=11712

可以说Robbin是用心思考后才作出这个总结的,这个总结很有意思,也很有道理。但是并不能说全对,说实在话,我对于技术的观点一直是反反复复的,这个反复是随着我对技术的一种体会而来,可能先对后错,也可能先错后对,但是无论怎么反复最终的观点我个人认为还是无限接近于正确的。    
先撇开Marin fowler的观点不说,因为引入他的结论无异于导致另外一种争论。
Robbin一直坚持这么一种观点:领域模型依赖于DAO接口是很evil的。
可以说这种观点不是很正确的,正如Rod Johson说的一样,这个依赖的划分应该基于重用性来进行划分。正如领域模型依赖于DAO似乎是一道很难逾越的门槛一样,逾越了这道门槛会带来很多东西。也可以将领域模型带入一个高度:即更加OO的一个高度。

然而,逾越这个门槛会带来一些问题,首先一点是单元测试的问题,DAO是很薄的一层接口,单元测试可以MOCK或者建立有效的测试步骤来解决。
另外一点就是跟现在ORM流行的实体数据类有一种微妙的冲突,HIbenate以及JDO,甚至到现在的EJB3 data persistence ,都给实体无形中框定了一个套子:数据+ 紧密依赖此对象状态的业务逻辑。

这个套子本没什么错,但是我觉得还是一个限定了OO的套子,紧密依赖此对象状态的限定,意味着它要比考量可复用的业务逻辑还要严格很多。 也就暗示着这么一个结论:领域模型不应该依赖于DAO接口。这点在EJB3的callBacks体现无疑。 很遗憾,他们给出了太多或许错误的设计方法以及设计规范。因为他们设计的系统的缺陷而无情把可复用的OO精髓扼杀在了产品规范上。

说道OO,我觉得我很有必要说我对OO的观点,不谈那些流行的设计模式,只谈一点,我认为最核心的一点:
真正的OO设计应该是类似事件传播的一种机制,而不是一种ActionScript/过程编写的手法。这点在Martin fowler 的企业设计模式里提到, 虽然仅仅一小章节提到这个观点,但是无疑这句话道出OO精髓,附件中给出简单的示意图。

道理确实太简单,估计很多人会不屑,但是我反倒觉得这个道理因为太简单而导致其意义最深邃.        
关于OO我仅提这么多。下面接着上面的正题。

一个合理的领域模型框架可以是这样:

                    Account---------------->DAO---------------->DB.

到具体的应用开发的时候,结合应用逻辑可以那么就是这样:
Facade--->App Logic--><Domain model>-->DAO-->DB
                
                App Logic
                   |
                    _-----------------DAO-->DB

    
在Application Logic这一层来定义事务边界。
我认为:基于是否依赖于数据持久层来决定业务 逻辑是否应该放在Domain model中这个说法,无论如何都是一种近乎苛刻的限制,而且这种说法也会最终导致Domain Model不得不在其上再套上一层所谓的Domain Model Manager层,这层才是真正存放大部分的业务逻辑。 最终导致这一层形成类似的Action script开发的方式。也最终限制了OO在业务领域模型的设计。


那个解释OO式设计的图例有问题,好的OO体系不应该建立这种单向线性依赖关系,相反应该采用第二个所谓的过程式设计,理由很简单,适应变化的能力。当需求有变动的时候,我们可能需要在Entity0和Entity1之间插入Entity4,按图一的设计,变化将影响Entity0和Entity1,而图二的设计只影响Actor0。用这种方式来区分OO设计或过程设计不是很贴切。
0 请登录后投票
   发表时间:2005-09-14  
age0 写道

那个解释OO式设计的图例有问题,好的OO体系不应该建立这种单向线性依赖关系,相反应该采用第二个所谓的过程式设计,理由很简单,适应变化的能力。当需求有变动的时候,我们可能需要在Entity0和Entity1之间插入Entity4,按图一的设计,变化将影响Entity0和Entity1,而图二的设计只影响Actor0。用这种方式来区分OO设计或过程设计不是很贴切。

此言差矣噢。
按照第二种方式,Actor0就是无所不知的上帝了。它必须了解所有实体对象的知识,才能完成业务,职责肯定单一不了。
相反在entity0和entity1之间插入entity4,如果他们之间生存周期是从短到长的关系,并且这种驱动在业务上是合理,那么这种插入就没什么不好。例如:最初只有“客户帐户”和“交易事件”这两个业务对象,通过“交易事件”来驱动“客户帐户”余额的变化。随后在它们之间插入“定单”对象,驱动关系变为“交易事件” -->"定单"-->"客户帐户"。

按照我的观点,业务对象本身就是一过程。整个业务的驱动的方式都是短时间对象-->长时间对象。
0 请登录后投票
   发表时间:2005-09-14  
hostler 写道
理论上讲是成立的,但在和现在的O/R映射工具很难结合起来,因为HIBERNATE等工具的"工作单元"实现大部分是"工作单元控制器"方式而非调用者注册或者领域模型注册的方式.请教firebody,JDO是否也是这样?
引用
事务属于持久化的范畴,完整的持久化Aspect应当包含它。

    事务不属于持久化的范畴,好像讨论过多次了

是啊,hibernate没提供。但这不等于很难结合。弄个Aspect就可以解决。

事务不属于持久化的范畴,那hibernate里的transaction是干啥的?
0 请登录后投票
   发表时间:2005-09-14  
要实现领域模型模式,BizObject实例是一定要得到Hibernate Session的,因为在BizObject的业务方法里要用它来访问别的对象,除非这个BizObject就只有Get/Set。
我看EJB3的作法不错的,EJB3可以在EntityBean中加个
@PersistenceContext EntityManager _em;
容器会自动注入这个EntityBean所用的工作单元,这套方法用Hibernate也能实现,就能实现完全OO的业务层了,而不是XXXManager+Entity的方式。
0 请登录后投票
   发表时间:2005-09-14  
partech 写道

此言差矣噢。
按照第二种方式,Actor0就是无所不知的上帝了。它必须了解所有实体对象的知识,才能完成业务,职责肯定单一不了。


此言差矣。
在任何一个具备一定规模的复杂体系当中,上帝的存在是必不可少的,因为协同管理不但是一种职责,而且还是至关重要的职责,根据职责单一原则,这个职责只能分配给管理者。一个好的体系应该是图一和图二两者的结合,图二着重于协调调度管理,图一则着重于反映单一事务的线性依赖关系,因此不能简单的将两者两分为OO式设计或过程式设计。
0 请登录后投票
   发表时间:2005-09-14  
大家心目中说的那些概念的意义不同(领域对象,应用逻辑对象等),造成了沟通的歧义。

我也乱抛几个观点:

1、说到OO,“事件传播机制”的本质是什么?我认为是Bob大叔多次谈到原则:单一职责原则:即:把事情交给最会干这件事情的对象。
2、领域对象>>持久对象 (>>意为远远大于)
3、凡事都有其环境,何谓业务逻辑?大多数的企业应用的信息系统还是围绕着数据转的。同为信息系统,逻辑复杂性强的和逻辑复杂性弱的系统的架构就一定要套一个模式?当然不是,所以呢,大家应该结合自己的项目特征来确定自己的架构。
0 请登录后投票
论坛首页 Java企业应用版

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