Application Layer [his name for Service Layer]: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.
Domain Layer (or Model Layer): Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.
据说在Thoughtwork公司里面采用的技术是Hibernate+Spring+webworkQ关于anemia domain model有不员工在公司内部邮g中发问老马应该什么正用。但是老马q没有给出确切答案,只放入TODOList厅R?BR>我个的DomailcM不应该含有过多的与之无关的行为,不但q反了单一职责的原则,q得整个系l不够稳定。例如User中有RolesQ那么addRole,removeRole自然应在DomaincUser中写Q至于removeUser,loadUser{应该封装成Daod理?BR>
引用robbin在一ơ讨Z的回复:
我的理解是Martin大叔所谓的domain object是?SPAN style="COLOR: red">领域模型”,它是一个针对业务逻辑抽象的模型,和Y件编E根本毫无关pR即使你不开发这个YӞ你仍焉要抽象你的业务逻辑得到你的领域模型?SPAN style="COLOR: red">q个领域指的是你所从事的行业,而不是狭隘的持久化类?
q且领域模型的徏模也是在需求分析阶D,或者在需求分析阶D之前完成的事情。具体到~程的过E中Q领域模型ƈ非对应某一个Javac,如果一定要对应的话Q(业务对象QDao接口QHibernate实体c)他们合v来统U领域模型在Java语言的实现。把 商业建模范畴的“领域模型”拿来当做Hibernate~程中的实体c,Ҏ是牛头不对马嘴!
其实你的d是把持久化实体cȝ持久化操作附着到实体类上面去,而不是分开。D例来_也就是说Accountcȝ增删Ҏ不应该单独分dAccountDao接口去,而应该把增删Ҏ操作攑֜Accountc里面来完成Q对不?
那么我在解释q个问题之前Q必L清一点,是q个问题的讨论,x久化操作是否应该单独抽象一个DAO层的问题是和Martin Fowler提到了血的领域模型毫无关pȝ。实际上传统的Entity Bean是q种把持久化操作附着到Entity Bean本nȝQ但是Martin Fowler一样在_q种Entity Bean是贫血的?
好了Q我们现在把其他无关因素排除了,focus到这个话题上Q就是我们是否需要DAO接口的问题了。因为按照你的观点,如果把对象的增删Ҏ都放在实体类上面Q其实我们就不需要DAO接口层了Q业务对象和Web Action都可以直接调用实体类本n来完成持久化操作了?
大概?003q以前,我一直就是采用这U模型的Q但是从2003q开始,我就Ҏ了分M个DAO层来专门处理持久化操作了。原因是多方面的Q从技术角度来考量的话Q分d有很多好处,Rod Johnson在《without EJB》第10章持久化里面pl阐qC需要DAO层的理由Q我你看一下,q里不复qC。只谈一下除了Rod Johson提到理由之外的理由:
作ؓ保持状态的实体c,他的职责是保持状态,而不负责状态的持久化。如果把持久化操作也攑֜实体cMQ一斚w来说Q把两种不同的职责放在一个类中,q不W合OCP的单一职责的原则,然而更重要的原因是会带来实体类的不E_的问题?
在我的理念中Q实体类以及实体cd联关pL一个Y件系l中最E_不变的部分,在整个Y件系l中Q各个层面都需要涉及到实体cȝ操作Q如何划分实体类Q以及确定实体类兌是最费考量的,定了这一点,整个软gpȝ底层依赖关pd被确定下来了Q实体类的属性可以变化,׃软gpȝ对实体的操作都是以实体类为单位的Q所以实体属性的变化不会造成pȝ不稳定)Q上面的DAO层,业务层,Web层都只对实体cM生单向依赖?
如果你把DAO层合q到实体cMQ请注意本来Web层是不依赖于DAO层的QWeb层只依赖实体c(因ؓ它要展现实体cȝ态)Q但是由于你合ƈ了,使得Web层也变得依赖那些DAO层的操作了。这Ll果是让Y件系l的耦合性提高,可~性降低,可维护性降低?
DAO层的变动是大于实体类变动的,实体cd本上E_不变Q而Y件系l的需求变更几乎一定会带来DAO层的变动Q但是ƈ不会带来实体cd的变动(会带来实体属性的变动Q但是很会影响到实体类本nQ。所以DAO层的变动频率q远大于实体cR那么当你把DAO层操作合q到实体cM后,其结果就是让实体cȝ变动频率{于DAO层的变动频率。那么就会造成本来E_的实体类层变得变得频率高了很多,而实体类的变动会波及到Y件系l的每个层面Q造成软g大面U的相关性和不稳定?
误住很重要的一点:实体cL有状态的c,DAOcL无状态的c,在整个Y件系l中Q只有两U类有状态,一个是实体c,一个是HTTP Session。有状态的cM带来很高的代码相x,应该量减少有状态类的媄响范_量减少有状态类的变动频率,应该量减少有状态类的职责?
而你把DAO操作合ƈ到实体类以后Q结果就是扩大了有状态类的代码相x的范围和媄响范_扩大了有状态类的变动频率,最后就造成软gpȝ的稳定性下降?/EM>