一月 25 2007

领域模型的设计问题

关于领域模型的设计问题,JavaEye已经组织过n多次大规模讨论,几乎每过一段时期就会出现一次。最近出现了一个新的趋势,Craig Walls在自己的blog上面写一篇文章,介绍如何使用Spring2.0AspectJ的新特性给domain object注入DAO依赖, 即如何实现post-instantiation,请见:http://jroller.com/page/habuma?entry=spring_2_0_vs_the 与此同时,ajoo也给出了nutspost-instantiation方案,请见: http://www.javaeye.com/display/ajoo/Dependency+Injection+For+Rich+Domain+Model 因此,从技术手段来上说,对于Spring/Hibernate?架构,MartinRich domin model变得可行了,那么让我们看看究竟有哪些领域模型,
 
以及他们的优缺点:

一、失血模型

失血模型请看 http://forum.javaeye.com/viewtopic.php?t=11712 中列举的第一种模型,简单来说,就是domain object只有属性的getter/setter方法,没有任何业务逻辑。

二、贫血模型

贫血模型请看 http://forum.javaeye.com/viewtopic.php?t=11712 中列举的第二种模型,简单来说,就是domain ojbect包含了不依赖于持久化的领域逻辑,而那些依赖持久化的领域逻辑被分离到Service层。 Service(业务逻辑,事务封装)->DAO -> domain object

这种模型的优点:

1.   各层单向依赖,结构清楚,易于实现和维护

2.   设计简单易行,底层模型非常稳定

这种模型的缺点:

1.   domain object的部分比较紧密依赖的持久化domain logic被分离到Service层,显得不够OO

2.   Service层过于厚重

三、充血模型

充血模型和第二种模型差不多,所不同的就是如何划分业务逻辑,即认为,绝大多业务逻辑都应该被放在domain object里面(包括持久化逻辑),而Service层应该是很薄的一层,仅仅封装事务和少量逻辑,不和DAO层打交道。 Service(事务封装) -> domain object <-> DAO

这种模型的优点:

1. 更加符合OO的原则

2. Service层很薄,只充当Facade的角色,不和DAO打交道。

这种模型的缺点:

1. DAOdomain object形成了双向依赖,复杂的双向依赖会导致很多潜在的问题。

2. 如何划分Service层逻辑和domain层逻辑是非常含混的,在实际项目中,由于设计和开发人员的水平差异,可能导致整个结构的混乱无序。

3. 考虑到Service层的事务封装特性,Service层必须对所有的domain object的逻辑提供相应的事务封装方法,其结果就是Service完全重定义一遍所有的domain logic,非常烦琐,而且Service的事务化封装其意义就等于把OOdomain logic转换为过程 的Service TransactionScript。该充血模型辛辛苦苦在domain层实现的OOService层又变成了过程式,对于Web层程序员的角度来看,和贫血模型没有什么区别了。

四、胀血模型

基于充血模型的第三个缺点,有同学提出,干脆取消Service层,只剩下domain objectDAO两层,在domain objectdomain logic上面封装事务。 domain object(事务封装,业务逻辑) <---> DAO 似乎ruby on rails就是这种模型,他甚至把domain objectDAO都合并了。

该模型优点:

1.   简化了分层

2.   也算符合OO

该模型缺点:

1.   很多不是domain logicservice逻辑也被强行放入domain object ,引起了domain ojbect模型的不稳定

2.   domain object暴露给web层过多的信息,可能引起意想不到的副作用。


在这四种模型当中,失血模型和胀血模型应该是不被提倡的。而贫血模型和充血模型从技术上来说,都已经是可行的了。

但是我个人仍然主张使用贫血模型。其理由:

1.   参考充血模型第三个缺点,由于暴露给web层程序拿到的还是Service Transaction Script,对于web层程序员来说,底层OO意义丧失了。

2.   参考充血模型第三个缺点,为了事务封装,Service层要给每个domain logic提供一个过程化封装,这对于编程来说,做了多余的工作,非常烦琐。

3.   domain objectDAO的双向依赖在做大项目中,考虑到团队成员的水平差异,很容易引入不可预知的潜在bug

4.   如何划分domain logicservice logic的标准是不确定的,往往要根据个人经验,有些人就是觉得某个业务他更加贴近domain,也有人认为这个业务是贴近service的。由于划分 标准的不确定性,带来的后果就是实际项目中会产生很多这样的争议和纠纷,不同的人会有不同的划分方法,最后就会造成整个项目的逻辑分层混乱。这不像贫血模 型中我提出的按照是否依赖持久化进行划分,这种标准是非常确定的,不会引起争议,因此团队开发中,不会产生此类问题。

5.   贫血模型的domain object确实不够rich,但是我们是做项目,不是做研究,好用就行了,管它是不是那么纯的OO呢?其实我不同意firebody认为的贫血模型在设 计模型和实现代码中有很大跨越的说法。一个设计模型到实现的时候,你直接得到两个类:一个实体类,一个控制类就行了,没有什么跨越。 关于领域模型的问题,限于时间原因,暂时不能展开详谈,待有空,写篇更加详细的文章。

评论

2010/5/23 5:26:09
China travel
信息是非常有用的..感谢分享
2010/5/23 5:27:08
chaussure nike
This is a really good read for me, Must admit that you are one of the best bloggers I ever saw.Thanks for posting this informative article.
2010/5/23 5:27:49
chaussure nike
This is a really good read for me, Must admit that you are one of the best bloggers I ever saw.Thanks for posting this informative article.
2010/5/23 5:29:56
Butterfly valve
You should really moderate the comments here
2010/6/17 11:57:52
replica watches
good
2010/6/25 13:11:59
cheap fashion handbags
Here you will find the best articles relating to everything cheap fashion handbags and the handbag market. We will discuss shopping tips, fashion trends, cheap brand wallets, and many more topics of interest to our wholesale customers! http://www.freewholesale.net
2010/7/17 0:42:30
Cheap Mattresses
This is a cool adn nice read. The blog is written in such a way that it is so easy to read and understand. I AM a fan of your blog. Thanks for sharing this information.
2010/8/6 2:17:07
ed hardy clothing
That's great, I never thought about Nostradamus in the OR (Insights from Eugene Litvak at IHI) like that before.
2010/8/26 22:49:37
vigrx
your site layout is very good

添加评论


(将显示你的Gravatar图标)

  Country flag

biuquote
  • 评论
  • 在线预览
Loading