论坛首页 Java企业应用论坛

读hibernate in action 和 PEAA 后发现感到的迷惑

浏览 5281 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-12-26  
在此之前我一直认为一般的分层结构是这样:表现层-〉BO-〉DAO-数据库;可能是我的理解又问题我一直认为DOMAIN OBJECT 就是我理解的BO,看了这两本书的前面几段都提到grain domain object 是包含业务业务逻辑的,和我的理解一致,但是到了后面 O/R mapping 的时候却发现两位大家的处理惊人的一致那就是O/R MAPING ,也就是dao是完全操作bo的,也就是说dao依赖于domain object. Domain object 完全不处理持久化的事务.结构就成了这样的 表现层-〉BO-〉DAO->(domain object,数据库)当然domain object 也不依赖于数据库的. 那么怎么才是作出好的BO呢?难到就是bussiness service 这一层才真正对应于BO?但PEAA中建议 bussiness service 应该尽量thinner,所有有点迷惑,难道直接爱MVC的控制层里面直接调用dao和domain object?请各位指点一二?
[/list]
   发表时间:2004-12-26  
引用
下面的代码<2><3>可以合并为一个操作 order.removeByItemName("tv")

从完全自然的角度来看下面这个用例:
引用
我的订单号是001,我要求取消我定的10样货品中的电视机那一相
那么什么都不考虑.我的最自然的想法大概是这样的(只是个例子流程,当然也不一定要是这么个顺序)
<1>Order: order =getOrderByID(String ID);;
               <2>Map orderItems=order.getOrderItems();;
               <3>orderItems.remove("电视机");;
          <4>save(order);


这里有个问题<1><4>两个操作放在什么地方呢?
这里有AB两个解决方案:
A:放在DAO里面(hibernate in action 就是这么作的<意思上是一样的>):

<1>Order: order =OrderDAO.getOrderByID(String ID);;
               <2>Map orderItems=order.getOrderItems();;
               <3>orderItems.remove("电视机");;
          <4>OrderDAO.save(order);

 
但是注意了DAO反回的对象是grained domain Object ,也就是OrderDAO依赖于 Order.这个思维也和PEAA的作者思维一致{order.getOrderItems(); 这一步很有可能也需要访问数据库}.但是这也有个问题1-4这部分代码在哪里?MVC中的CONTROL层?好像不是很好.另外写个SERVICE层orderService?

   OrderService.removeByItemName("orderID","TV");; //全是静态方法?面向过程!
 

但是这个SERVICE层明显是由问题的:面向过程!更严重的是如果要加入一个item 电扇 怎么办?:

 OrderService.addItem(Item fan);; //item本身是一个domain object
 
那肯定是OrderService的调用者实例化,那格调用者既依赖于sevice 又依赖于domain object,层的关系混乱。martin也建议service层近量thinner.当然这样做有个好书容易测试。业务对象的操作和数据库无关。
B:用Order 包装dao 用
]

<1>Order: order =Order .getOrderByID(String ID);;
               <2>Map orderItems=order.getOrderItems();;
               <3>orderItems.remove("电视机");;
          <4>order .save(order);

 
这个方案看上去要更为优雅,mvc 的control层只要了解domain object就可一了,可能测试的时候比较复杂。要操作数据库。为什么大师们都选择A方案?紧紧是为了测试的原因?
0 请登录后投票
   发表时间:2004-12-27  
看了partech的一文<Domain Model 探索>我感觉脑子清楚一点, domain  object和OR/MAPING(dao),的关系和partech 
引用
<Domain Model 探索>
一文的 act 和 commitment的关系有点像。自然的语义和依赖关系的不一致:
引用
自然语义是:我生成了一个订单我要保存它
但是看看 hibernate in action 的caveatemptor的例子:
引用
它的语义是:我生成了一个订单,我找到了一个dao,我用这个dao 把订单保存起来
而java中的真正依赖关系是dao 必须要知道 domain object的结构才能保存。很显然 hibernate in action 的caveatemptor的例子 更加 贴近 java的语义也就是A方案。
B方案更贴近自然语义,但是不符合类的依赖关系,那么能不能借鉴
引用
<Domain Model 探索>
一文的的处理方式:DIP
   Order: save();{
     IOrderDAO  orderDAO=  OrderDAOFactroy.getDAO(this);;
     orderDAO.save();;
}

Interface IOrderDAO implement IDAO{
.......................
}

class OrderDAO  implement IOrderDAO{
Order order;    
public OrderDAO  (Order order );{
   this.order = order 
   }
}


当然也可以使用继承,对了这里还要感谢partech 说的依据让我恍然大悟的话::
引用
接口属于调用者!
一句话把我从包的划分的问题中解脱出来了
0 请登录后投票
   发表时间:2004-12-27  
DDD中写道
引用

Layers are meant to be loosely coupled, with design dependencies in only one direction. Upper layers can use or manipulate elements of lower ones straightforwardly by calling their public interfaces, holding references to them (at least temporarily), and generally using conventional means of interaction. But when an object of a lower level needs to communicate upward (beyond answering a direct query), we need another mechanism, drawing on architectural patterns for relating layers such as callbacks or OBSERVERS

有点觉悟了,分层,那一层再上面,那一层在下面和依赖本身无关。domain object 肯定在dao之上,下层的dao要和上层domain object 交流,就用dip ;
OBSERVERS  就是DIP的一种很好的pattern.
IOrderDAO把自己注册在Order 中,Order 就可以很方便的调用了。
0 请登录后投票
   发表时间:2004-12-28  
还有个问题OrderDAOFactroy本身要返回一个具体的orderDAO是否又会造成对dao的依赖呢?难道还要用ioc来解决?觉得好像越来越烦了,有没有更好的解决方法?
0 请登录后投票
   发表时间:2005-01-01  
frankensteinlin 写道
还有个问题OrderDAOFactroy本身要返回一个具体的orderDAO是否又会造成对dao的依赖呢?难道还要用ioc来解决?觉得好像越来越烦了,有没有更好的解决方法?

domain object 当然不必ioc了,不然配置文件多繁琐.
方案a当然是可取的.
&lt;1&gt;Order: order =OrderDAO.getOrderByID(String ID);
               &lt;2&gt;Map orderItems=order.getOrderItems();
               &lt;3&gt;orderItems.remove("电视机");
          &lt;4&gt;OrderDAO.save(order)
但Domain Object可以拥有数据库Mapper,
这样就优雅的可能支持ddd了
0 请登录后投票
   发表时间:2005-01-12  
A:方案有个缺点前面讲过了:OrderDAO.save(order)
由谁来调用?

看了spring的实现方式,直接由spring 的factory拿到ado的接口就可以很好的支持B了。

用户只要和domain object 打交道就可以了。
0 请登录后投票
   发表时间:2005-02-03  
我读PoEAA后感觉是 BusinessLogic(BO) + BusinessData(PO) = Domain Object,Service层只是简单调用Domain Object而已,这也是Service层作为Facade的职责特点,他不应包括真正的 BusinessLogic (到有可能包含一些Use case相关逻辑)。

不过如果是这么做的设计(BusinessLogic(BO) + BusinessData(PO) = Domain Object),倒产生另外一个问题 即产生了Domain层对DAO层的依赖。(因为实际应用中许多Domain Object的create/update/delete都有相关的业务限制,而这些业务限制又大量涉及到数据库中已有数据的状态。)

这是前些天的一个讨论。
http://forum.iteye.com/viewtopic.php?t=10571
0 请登录后投票
论坛首页 Java企业应用版

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