贫血和充血模型的比较之我见->有兴趣的朋友进来参与讨论

今天在jdon看到一片关于领域模型的文章,心里总结了一下


下面是个人观点!

贫血模型是对OO的非常经典的诠释!数据交给s/g,业务全部交给业务对象来完成。耦合度很低,逻辑清晰,重构空间大!而且在业务逻辑上事务控制的关注点也小!但是也很明显,业务对象做的事情实在太多了,在领域对象上这个叫做超职责。s/g和业务对象分工虽然明确但工作量截然不同, 也就是说这个对象的职责过于复杂,在一定程度上背离了细力度的oo模型原则。


充血模型我个人认为是可取的!


1:把一部分有针对性的简单逻辑交给s/g去完成,把业务对象向轻量级转换,但是这里就存在了一个设计上的问题!业务并不是完全由业务对象去完成,2者之间的职责就不明确了,同时事务的控制范围也要扩展到s/g这一层上来,整个系统的模块之间就没有明确界限,理解上来存在门槛问题!但是就设计上来说,这是一种进步!只是团队开发的今天,充血模型在推行上存在障碍!



[该贴被zuly于2007年04月05日 10:36修改过]

楼上总结不错,基本将两个模型特点总结了一下.

我个人观点是:这些都是纯设计领域的考量,重要的是还是要掌握,设计遵从分析.从这点来说,Evans DDD已经给了答案.

虽然MF在他的文章中引论了Evans DDD的服务概念,用来证明它的贫血概念:
http://martinfowler.com/bliki/AnemicDomainModel.html

这实际是片面的, Evans DDD还有关于模型定义是:领域模型分三种实现模式:实体对象 值对象 和服务,值对象就是valueObject,实际就是数据对象,是贫血的,实体对象有时也是.DDD将这三种模型合起来成为充血模型,但是具体实现,你可以分开实现.
Evans DDD突出的是分层.

当然,Evans和MF共同点就是:服务这个概念,服务分领域层和应用层,关键业务必须放到领域层,我在开发jivejdon3.0时,基本依据以上模型思维来进行.

我的观点:象楼主这样简要理解对比一下充血或者贫血是合适的,但是,如果只在纯设计领域一定比较要得出结果呢,就类似鸡生蛋 蛋生鸡的饶舌问题,将简单问题复杂化了。

分析比设计重要,只要分析时坚持完整丰富领域模型概念就可以,在目前情况下,OO设计和OO分析不是一定要100%对应的,因为OO设计必须考虑更多技术平台因素


[该贴被banq于2007年04月05日 18:19修改过]

楼上会选哪种!

充血模型对项目组平均水平要求很高,特别是事务处理上。我尝试过一次,没有走通

说实话,个人不喜欢贫血模型,因为可能我不喜欢框架的原因吧
觉得这种设计纯粹是为了框架设计而产生的,不符合设计的初衷
充血模型对人员要求很高,而且可能觉得可移植性不是很好
可是我做过的项目需要移植根本就不多,顶多是一些util可以重用

>楼上会选哪种,充血模型对项目组平均水平要求很高,特别是事务处理上。我尝试过一次,没有走通

2002年的Jive2.5其实就是充血模型,而今天的JiveJdon3.0则是依据Evans DDD实现分实体对象、值对象和服务的混合模型。

之所以有贫血和充血区分,其实还是分析切入角度有问题,思维是数据库分析思维,才有数据和行为的分别。而按照DDD这个模型分析方法,是从另外一个角度来进行模型提炼,也就巧妙地回避了这个问题,DDD重视将业务核心放入领域层。

这其实就是看事情的角度不一样,如果我们思维不从一个全新分析方法切入,而是按传统的分析方法,必然就会碰到贫血和充血问题,从而陷入一个鸡蛋问题。

所以,Evans DDD确实是这几年了不起的革命性的分析思想。
[该贴被banq于2007年04月08日 09:03修改过]

“爱玩斯”的“道道道”是好思想啊,哈哈……

啥叫贫血?啥叫充血?

能否真诚的恳请banq老师较为明确的指点一下Entity model object和 Value object之间的不同,同时也希望能用个很简洁的例子示意一下Service model object的用法,因为个人感觉Domain model这里似乎是一切应用开发的源头(新手的感觉啊,未必当得真),于是个人的困惑似乎也总是spoke在此...挚谢了

我的文章“关于贫血模型”难道还没有剖析透彻吗?

回去想了下,觉得领域模型应当是下面这个公式:
领域模型 = 贫血类(实体、值) + 服务类
贫血类:静态的,在表现层作为DTO,在业务层作为POJO,在持久层作为PO
服务类:组织一个场景,添删改查贫血对象POJO进行业务操作;

想来想去,觉得在三层架构中还是用贫血类最好,减少了在各层间转来换去的许多冗余类;

不过我还是觉得贫血模型不是很面向对象的。有点回归原来的面向数据流的分析与设计了。把数据流(贫血类)与业务处理(服务类)分开,原来在业务处理方法中拼装sql语句直接对数据库进行操作,现在是对贫血类进行操作;业务负载换了个地方,原来是数据库,现在是应用服务器。