论坛首页 Java企业应用论坛

谈一谈贫血的Domain Logic问题。

浏览 42599 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-03-22  
引用
业务逻辑的实现难道不会依赖于实体保持的状态?将它们放在一起就是封装。


只有要依赖关系就一定要封装到一个类里面吗? 请看我这个帖子举的例子:

http://forum.iteye.com/viewtopic.php?t=11608

Struts Action的execute方法:

execute(HttpServletRequest request, HttpServletResponse response, ActionFormBean formBean, ...);;


execute方法依赖HttpServletRequest,根据你的逻辑,execute的实现依赖于request保持的状态,所以要把execute方法放到request里面进行封装,哈哈。挺荒谬的吧,为什么会这样? 因为你把两个类之间的调用关系当做了类的行为了。请注意,什么情况下一个方法行为应该封装到类里面,什么情况下一个方法行为只不过是消息的消费者必须清楚的区分。
0 请登录后投票
   发表时间:2005-03-22  
Archie 写道
robbin 写道
我的理解是Martin大叔所谓的domain object是“领域模型”,它是一个针对业务逻辑抽象的模型,和软件编程根本毫无关系。即使你不开发这个软件,你仍然需要抽象你的业务逻辑得到你的领域模型。这个领域指的是你所从事的行业,而不是狭隘的持久化类

并且领域模型的建模也是在需求分析阶段,或者在需求分析阶段之前完成的事情。具体到编程的过程中,领域模型并非对应某一个Java类,如果一定要强行对应的话,(业务对象,Dao接口,Hibernate实体类)他们合起来统称领域模型在Java语言的实现。把 商业建模范畴的“领域模型”拿来当做Hibernate编程中的实体类,根本就是牛头不对马嘴!


把商业建模范畴的“领域模型”拿来做实体类,是一种最容易让人选择方法。我是常常都这么做了,做的过程中,再逐渐的为实体类加入业务逻辑,感觉还是经验不足啊。

我认为这个 是由 应用大小以及复杂程度决定的。。。如果业务不复杂 一个业务相关的领域模型模块 用一个类来设计当然没有问题。。。 但是 一复杂就不行了我想可能复杂到一定程度 数据结构 与 方法 分开由不同的类来实现 也是有可能的用 这时一个领域模型的每一个模块 就可能由一组类来实现。。。。
0 请登录后投票
   发表时间:2005-03-22  
领域模型的概念 是软件工程中的基本概念。。。已经没什么好讨论的了。。。

service 由一种 O来实现 也应该是 Biz Object 而不是 PO。除非 业务简单 Biz Object 本身就是PO。加在PO上的“service”顶多应该只是一个helper 。虽然在实际当中可以灵活,而且PO与BO 重合 也常有 。但是个人认为 必须在概念上区分清楚。。。(BO 差不多就是 业务层 传给web层的dto )
0 请登录后投票
   发表时间:2005-03-22  
robbin 写道
引用
业务逻辑的实现难道不会依赖于实体保持的状态?将它们放在一起就是封装。


只有要依赖关系就一定要封装到一个类里面吗? 请看我这个帖子举的例子:

http://forum.iteye.com/viewtopic.php?t=11608

Struts Action的execute方法:

execute(HttpServletRequest request, HttpServletResponse response, ActionFormBean formBean, ...);;


execute方法依赖HttpServletRequest,根据你的逻辑,execute的实现依赖于request保持的状态,所以要把execute方法放到request里面进行封装,哈哈。挺荒谬的吧,为什么会这样? 因为你把两个类之间的调用关系当做了类的行为了。请注意,什么情况下一个方法行为应该封装到类里面,什么情况下一个方法行为只不过是消息的消费者必须清楚的区分。

没错你说的情况是使用关系。
但不要断章取义,后面还有论述呢。
partech 写道

因为业务逻辑依赖于实体的状态,否则它就没有操作的对象,同时实体的状态也需要业务逻辑的解释,操作和变换。否则它就毫无意思。这种双向依赖的关系,就导致
需要将两者放入同一个的结构中,这就是OO中的类。

举个例子,订单的状态,当客户下了订单后,状态变为“已下单”,随后客户通过网上银行划款,订单状态变为“已付款”。概念上订单的状态已经暗示着“下单”,“付款”的业务操作。因此说订单状态依赖于上面的业务操作。

双向依赖的关系就需要合并,软件当中也有分形的影子。较大尺度的处理是把两个相互依赖的类放入同一个包中。较小尺度上相互依赖的操作和数据就需要放入同一个类中。
0 请登录后投票
   发表时间:2005-03-22  
引用
双向依赖的关系就需要合并,软件当中也有分形的影子。较大尺度的处理是把两个相互依赖的类放入同一个包中。较小尺度上相互依赖的操作和数据就需要放入同一个类中。


双向依赖的关系就必须放在一个类里面对吧?

先不说你自创的理论多么荒谬,就看看Dao接口和实体类是否双向依赖,我想这并不难判断吧?
0 请登录后投票
   发表时间:2005-03-22  
robbin 写道
引用
双向依赖的关系就需要合并,软件当中也有分形的影子。较大尺度的处理是把两个相互依赖的类放入同一个包中较小尺度上相互依赖的操作和数据就需要放入同一个类中


双向依赖的关系就必须放在一个类里面对吧?

先不说你自创的理论多么荒谬,就看看Dao接口和实体类是否双向依赖,我想这并不难判断吧?

唉,老兄不知道是我没说清楚还是你太粗心
你说的符合较大尺度的处理是把两个相互依赖的类放入同一个包中
而不是较小尺度上相互依赖的操作和数据就需要放入同一个类中

这个理论可不是我自创的。
数据同操作的封装成类,是我在学习OO是最早接触的概念。
我要是能创造“双向依赖的类放入同一个包”这样的原则。我就可以像Robort Martin 一样也出一本万人期待的书了。
0 请登录后投票
   发表时间:2005-03-22  
好好,是我粗心。 原来是:

引用
较大尺度的双向依赖要放在一个包里面的不同类
较小尺度的双向依赖要放在一个类里面


原来如此啊,呵呵,我不说什么了。大家自己去考虑这句话吧。

问题讨论到这个份上,该清楚的地方都清楚了,该怎么做大家自己去做做就明白了,再讨论下去就是强辩了,我撤了
0 请登录后投票
   发表时间:2005-03-22  
robbin 写道
好好,是我粗心。 原来是:

引用
较大尺度的双向依赖要放在一个包里面的不同类
较小尺度的双向依赖要放在一个类里面


原来如此啊,呵呵,我不说什么了。大家自己去考虑这句话吧。

问题讨论到这个份上,该清楚的地方都清楚了,该怎么做大家自己去做做就明白了,再讨论下去就是强辩了,我撤了

希望你引用完整,不要篡改我的原话,不过份吧?
partech 写道
双向依赖的关系就需要合并,软件当中也有分形的影子。较大尺度的处理是把两个相互依赖的类放入同一个包中。较小尺度上相互依赖的操作和数据就需要放入同一个类中。
0 请登录后投票
   发表时间:2005-03-22  
先不谈职责,不谈依赖,谈最基本的对象:什么是对象:数据+属于他自己的操作,这句话是不是权威不太清楚,反正我是这么理解的。
先不谈建模,不谈状态:说我自己的理解:一个系统有太多的没有数据的对象,或者有太多的没有操作的对象(简单的不做任何修改代码getset不计作操作)
这种设计好象是有问题的,不那么oo。似乎需要重构一下。
那么 有这么一个数组[123456] 然后有一组操作作用于数组,这两个是否要放在一起呢?我认为是近可能的是。

再看看现在流行的分层:
先由下而上:
后面是关系型数据库,没办法,它是最流行的,它就是一组纯粹的数据,再往前推推po,大部分是纯粹的数据类。外面有个dao,没有状态的,来操作这个po,再往外面
用service调用ado把把数据区出来放到po里面,再调用bo处理最后呈现给用户,或者放回给数据库。这里有两个问题:为什么会有两层,一个没有操作一个没有数据?

再来看职责
bo 就负责内存中的计算,ado负责抽取盒回放数据,po负责存放数据本身,service负责提供伽ado和bo的组合隐藏起来,让用户得到尽量简单的接口。很明确,我们先不考虑性能,不考虑可实现性,性能
纸上谈兵,看看如何:把ado po 结合起来如何?本来ado要持久化po 就需要了解po的内部构造为什么不把数据和操作放在一起呢?po有了数据有了持久化的操作接口,这不是很好么?
要下班了,明天再谈讨把bo再访进来是否可行
0 请登录后投票
   发表时间:2005-03-23  
看了七彩狼,partech等人的讨论, 我的首贴的观点中关于将持久化功赋予DM基本是错误的。 我也逐渐这么认为!
我认为七彩狼的几个回帖还是很能说服我的! 
基本上可以这么总结(全部是个人的思考,如果有错误,请批评!):
partech 七彩狼 Robbin的观点是一致的,只不过他们之间的表述有些不一致。
虽然Robbin认为POJO是可以放入业务逻辑。 这个跟partech是一致的,但是他们在具体表述怎么实现复杂的业务逻辑时出现了表述的不一致。 Robbin认为这是Service的功能,而partech对这个Service的理解是它应该作为一个Service Facade,供应用层直接调用,Service应该调用具体的DM,DM代表实现各种复杂业务逻辑的模型,具有属于自身的业务逻辑的POJO也属于这层。只不过对于一个复杂的业务逻辑可能需要一个专门的领域对象调用协作的其他不同领域对象来完成。
说到底,他们的观点是基本一致的,只不过表达上出现了偏差。


对于一个基于内存模型的领域模型,数据持久的行为与领域模型是毫无关联的,然而一个具体的银行开户并不会简单得涉及到new Account()的这么一个行为,它会牵涉到多个对象的建立,以及执行相应的逻辑。将这整个 业务流程放在其中的某个对象均是不妥当的,这样的结果必然出现一个专么负责完成开户所有流程以及建立完成开户后完整的内存模型 的领域对象,很多人对于这么一个对象赋予不同的名词,一些人给他命名为Service,一些人给他命名为控制类,一些人给他命名为Act等等。 但是不同的人对于这么对象却有不同的理解,一些人认为这不属于DM,一些人认为这属于DM,一些人认为这是Transaction Script, 至于相应的数据持久化不应该出现在Domain model中,
至于说要赋予领域模型复杂查询的功能,这种说法确实很值得推敲.赋予领域模型复杂查询功能有可能是实现某些业务流程必要的步骤,那么就 给领域模型这么一个DAO接口!

我赞成用一个Service 调用一个领域对象的某个方法,完成一个具体业务的逻辑,然后进行调用具体的DAO进行数据持久化。


谢谢大家的热情! 因为我这么一个胡思乱想的帖子引发这么激烈的争论 ,这是意想不到赫!  嘿嘿,不过感觉自己的思路已经越来越清晰了! 谢谢大家!       
0 请登录后投票
论坛首页 Java企业应用版

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