各位看看这个(IB不良的I域模型)
http://www.dotspace.idv.tw/Patterns/anemic_domain_model.htm

有什么感想啊!!


下面上我的想法,我到是认为适当的应用所谓的“贫血模式”还是有必要的!!

在我所从事的应用当中,所谓USER
这样的一个CLASS我认为不错,没有必要把他和BUSSINE
CLASS 缠绕更多的关系!

public class User{
private int ID;
private String name;
private String password;
private int GroupID;
....
public void setPassword(String password){ ... }
public void changePassword(String password){ ... }
....
}

TO 浆糊,谢谢你能提出不同的想法,这才是一起探讨问题的意义。但我个人不敢苟同你说让我去看domain-model design这本书,说实在话,我不见的能出书的人他的水平就高,就算是是国外的作者也是,关键是自己在实践中对事物的理解,认识来自已实践的归纳。可以这样说我个人不大想对user类认为是一个domain-model,而只是一个数据载体的javaBean,对应于它的UserDao才是一个domain-model,但UserDao也只是一些简单的、原始的一些逻辑动作,就是以user做为数据载体来莆助完成它的逻辑。如果是业务逻辑应该在Command中实现。最后是一个Facade或Service Manager来提供客户端调用。我想说以下千万不要拘泥于domain-model的概念和什么什么书,对不起,我没有说不要信书,更重要的是自己对事物的理解很重要,只要自己的做法符合我们软件要求稳定性、易维护性、伸缩性,层次清楚就可以了,然后慢慢让自己进步。

banq,你谈谈你对贫血模型的看法。我觉得大家主要是从对象的方向来说明它的不好,认为贫血模型没有它自己的逻辑方法,呵呵,打根我就不认为贫血模型是域模型。而Entity Bean 才是 或者是Dao+贫血模型,呵呵,其实理解什么是域模型很重要,或者就根本不要去追究什么是域模型,只要知道这样做好就行了,概念不是本质的东西。

浆糊能否多多讲一下“真真实现业务逻辑纳入domain object并没有什么奇怪,它真实的反映了领域模型的行为,更符合OO,当然回带来更多的好处。”其实,这有些违背OO细分和封装的原则,domain object就是数据载体,业务逻辑应该被分离出去,独立封装,这才更OO阿。

领域对象,呵呵!!

对于专有名词,的确 说POJO、VO等都可以,JAVA专有名词多,也不是一次两次的事情了!我看这也算是一个简短的领域对象!!

我认为领域对象全部使用极为简单的VO。
其他需求通过wrapper模式外覆解决,不失为一种好主意!

没有DB,存储也是业务逻辑的一部分!!

比如有一个复杂的业务逻辑,用复杂的SQL可以实现,存储过程也可以实现,但用OO实现,那我们就可以使系统最大的可扩展、易维护,这就是领域模型的优势所在,我认为这就是领域模型的优势所在。

个人比较赞成浆糊所说的模型,我也认为应该分成业务逻辑类和业务数据累,由业务逻辑累来完成如楼主所说的修改密码,新增用户等操作,而不是由业务数据类来完成。我觉得这样的设计有利于整个系统的可扩展性。
如我们可以设计以下几个类:
BusinessServiceInterface接口,业务逻辑接口。
BusinessServiceImp类,业务逻辑实现类,其提供了具体的业务逻辑。
ServiceManager类,负责定位和公布不同的业务逻辑类接口。
BusinessData类,其为业务数据类。
这样的设计有如下的好处,当我们的业务逻辑变更时我们只需要修改或者新建立一个BusinessServiceImp类就可以了,不需要对其他类进行变更,对其他类几乎没有影响,但这样做有一个前提就是我们对BusinessServiceInterface的定义必须能足够的准确并保证不会进行变动,如果要进行变动这会带类整个系统相关模块的整体的变动。

偶也来放点獗词~~

以前好像多数是苗条的,而且大家都在想方设法的苗条,原因是程序员太懒惰,没人愿意开发维护一个硕大肥胖的域对象。

因为这个肥大的域对象需要一整套存储,操作,表现机制,而且要有事件、自描述等额外信息。在sap里面有,lotus里面有,java里面似乎还没成型。

最近也在思考这个问题,并且有了一些初步答案。
http://www.cnblogs.com/steeven/archive/2004/11/17/64605.html


Manager/Service个人认为是对象的静态方法。整个业务树应该有多个多个服务位于结点上。

Hi,nekesai
我觉得这书还不错,所以推荐你一下,还有就是Martin Flower的 Patterns of Enterprise Application Architec都是很好的书,不妨有时间看看。实践的经验是宝贵的,我并不否认,但是这些经典书籍也是我们这个领域中的一些资深开发者的经验之谈,所以说,看看是有好处的。
至于逻辑处于service/manager中好还是domain object中好,其实这些书中都有比较详细的阐述和比较。我前次的言论也是自己在实际开发中的一些感受,的确感觉domain object的方式在系统不断壮大的过程中可以带来不少的好处。
至于OO,我觉得domain object并没有违反OO的原则,反而是很好的遵循了这些原则。如果那位仁兄能指点一二,述说domain object方式违反了哪些OO原则,小弟将感激不尽。

我觉得,这个问题要看changePassword这个操作是属于业务逻辑还是应用逻辑,应用逻辑是指某一个具体应用所需的逻辑,领域对象应该是可以在多个应用中重用的,所以业务逻辑是一种比应用逻辑更通用的逻辑,是可以在多个应用中重用的。单单从搂住给出的信息看出changePassword这个操作到底是属于哪一种逻辑。如果是应用逻辑就应该放到服务层中去,反之就应该放到领域层中也就是域对象中。
如果只是把域对象看成值对象,那干脆不要用域对象得了,直接用Transaction Script和表接口方式不是来得更简单实用,省得要花精力去维护o/r mapping。
我想不通为什么贫血模型会方便实现组件化编程,我宁愿使用稍微膨胀的域模型,因为多出来的方法并不会妨碍域模型被用于多个应用,实体bean除了get,set外同样可以有很多业务方法。
Session bean可以被看成Transaction Script的实现,但我觉得它更像专门为服务层准备的。

我想说的是vo我只认为它是数据载体,更象元数据的集合。呵呵,我也很难认同它是域模型。硬要说域模型是什么,那我一直觉得vo+dao才是,或者entity bean。但为什么要单独的吧一些数据载体的javaBean如VO 出来批评呢,我就觉得很奇怪,偏要说她是一个贫血模型不好。有什么不好了,你把它当作域模型干什么了。人家本身就不是域模型,但它有它的用处,就是把域模型分开,对象细化,现在不是强调元数据编程吗,让一个域模型那么胖干什么了,瘦一点它的耦合性不是更弱,服用性更强,而且更容易抽象。entity bean干吗都要使用vo模式的了,当然主要是网络传输问题,但有没有考虑过,如果一个假设是一个local entity bean,那就不需要vo模式了吗?依然有它的用处,否则你的beanInstance.findAll()传回来的collection里是什么呀,一个个的Bean好呢还是vo好,因为在更多情况表示层需要的是数据,不是你的findAll()方法。那么你觉得通过网络系列化Bean的数据量大,还是vo的数据量大,显然是Bean的数据量大,因为它的一些导致所谓的不贫血的findAll()是要占byte的,而传过去的这些byte是垃圾,表示层是不需要它们的。

当然整体上大家的观点应该没有原则性错误。但我觉得做学问不要人云亦云,有什么了不起,对不对,当然我可以借鉴它,但我一定是以批判的观点去吸取它的对的地方,如果自己的做法在实际应用做真的出了问题,嘿嘿这才是最好的书本。当然了,开始的时候大家没有经验的时候总归是要学习,并且不容易批判的学习的。反正我的观点是vo我只认为它是数据载体,更象元数据的集合,呵呵,我也不认同它是域模型,如果有人那它当域模型来要求而批判它是什么贫血等等,我没有什么意见,但不能因为认为可以批判它它就不应该存在,呵呵,那就错了,因为它根本不是你想象中的域模型,在说一下,它有它的用处,更重要的是它帮助我们说的域模型的对象细化,操作和数据分离,有什么不好。呵呵

DAO不应该被包括在域模型里,它应该属于持久化层,其作用是把领域层的状态持久化。至于vo应该是用于服务层和表现层之的数据传递典型的DTO模式。
如果是VO+DAO方式,完全不用领域层,就有些不伦不类了,单从效率上讲
真的不如Transaction Script+表接口方式的开发效率高,
简单的业务确实不需要模型驱动的方式,直接用表驱动效率会更高些。用RowSet来完成表接口和视图间的传值还省去了对vo每个字段都要进行的set操作。其实我觉得VO+DAO方式中的DAO就是表接口了,只是从DAO得到的是用VO表示的一行或多行数据。

VO目前存在两种不同的对象(ViewObject,ValueObject),一种是作为显示视图.一种是作为数据传输,后来martin更名为dto的东西.这两种对象的确需要存在,但是任何事物的存在都是需要它的所适合环境的,或者说是上下文(Context).如果在一个没有远程调用的系统里面,为什么要用dto?这种情况下dto是令人讨厌的,我是绝对反对这种劳命伤残的事情.当然,它是有用处的,那就是减少远程服务中的数据传输,用ejb也好,用soap,burlap等等..发挥dto的作用吧,它能让远程调用更高效.如何更好隔离远程服务和本地服务?用Remote service facade吧,那样可以使你的远程服务接口更清晰更方便扩展,也许它是一种可选的设计方案,但它在很多情况下结构良好.ok,这就是我的观点,dto不是要消亡,它要存在,而且要很有价值的存在,如果让它存在于每个系统中,或者是没有远程服务的系统中,dto也算是反模式的一种.
做学问不要人云亦云,绝对100个正确!我是讨厌这种态度的,当然我也不会是这样一种态度.所有发表的言论,都是经过自己实践的经验之谈,当然,我在Martin Fowlerr,Robert C. Martin,Kent Back那里学到到了很多,所有他们的经验,经过自己的实践之后才又发言权.但是请注意,在没有完全理解一个概念或者一种设计方法的时候,千万不要先尝试去排斥它和下一些很主观的结论,就像一些人,连一个test case都没有写过就开始批判tdd的种种弊端,显然是底气不足的.如果不知道domain object,那么先去学习它,了解它,吸收它,批判它,如果它好,请肯定它.如果连概念都不清楚,何来批判!人云亦云不对,在对一个事物一知半解的情况去批判它更要不得.

rich domain object是oo设计中非常重要的,DDD(domain-driven design)是OO设计中正确的设计方法之一,目前普遍存在的service执行business logic的方式是Transaction Script,更多的是面向功能的结构化设计方式,在简单系统里面也许能很快的实现功能(这种情况下Transaction Script也许是一个合适的设计方案),但是大的系统里面代码重复,重用性较低,随着项目的增大,成本不断上升,它的弊端暴露无疑.service是需要的,它只是代理domain object的行为,给外界提供服务,它是facade,请参考经典设计模式,facade的作用何意图到底是什么.

浆糊说
“没有远程服务的系统中,dto也算是反模式的一种”,关于这一点我有点想不通,因为我觉得dto除了可让细粒度的rpc变成粗粒度的rpc外,还可以隔离服务层和应用层。
如果不用dto,服务层和应用层怎么传递数据?浆糊觉得应该用什么方式呢?