DAO與SERVICE

DAO:::::DAO實現對數據庫的操作.

SERVICE::::::Service實現業務邏輯的封裝,數據庫操作只是業務邏輯的一部分而已。

但是在實際應用中,建議使用Service+DAO,看似麻煩些,但分層能相對清晰一點。

總之,我還是很喜歡把DAO和SERVICE分開的。這樣起碼以後容易擴展並且看起來邏輯清晰.

看過的一篇帖子說:比如現在用hibernate 以後可能改爲jdbc或者其他的也比較方便,SERVICE是單純的進行業務邏輯處理調用DAO來持久數據,所以DAO和SERVICE還是應該要獨立的!

以下是我看到的一個帖子,總結的很好。做爲收藏.....

第二種模型,也就是Martin Fowler指的rich domain object是下面這樣子的:

一個帶有業務邏輯的實體類,即domain object是Item
一個DAO接口ItemDao
一個DAO實現ItemDaoHibernateImpl
一個業務邏輯對象ItemManager

java 代碼
  1. public class Item implements Serializable {  
  2.     //  所有的屬性和getter/setter方法同上,省略  
  3.     public Bid placeBid(User bidder, MonetaryAmount bidAmount,  
  4.                         Bid currentMaxBid, Bid currentMinBid)  
  5.         throws BusinessException {  
  6.       
  7.         // Check highest bid (can also be a different Strategy (pattern))  
  8.         if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) {  
  9.             throw new BusinessException("Bid too low.");  
  10.         }  
  11.       
  12.         // Auction is active  
  13.         if ( !state.equals(ItemState.ACTIVE) )  
  14.             throw new BusinessException("Auction is not active yet.");  
  15.       
  16.         // Auction still valid  
  17.         if ( this.getEndDate().before( new Date() ) )  
  18.             throw new BusinessException("Can't place new bid, auction already ended.");  
  19.       
  20.         // Create new Bid  
  21.         Bid newBid = new Bid(bidAmount, this, bidder);  
  22.       
  23.         // Place bid for this Item  
  24.         this.getBids.add(newBid);  // 請注意這一句,透明的進行了持久化,但是不能在這裏調用ItemDao,Item不能對ItemDao產生依賴!  
  25.       
  26.         return newBid;  
  27.     }  

<script>render_code();</script>

競標這個業務邏輯被放入到Item中來。請注意this.getBids.add(newBid); 如果沒有Hibernate或者JDO這種O/R Mapping的支持,我們是無法實現這種透明的持久化行爲的。但是請注意,Item裏面不能去調用ItemDAO,對ItemDAO產生依賴!

java 代碼
  1. public interface ItemDao {  
  2.     public Item getItemById(Long id);  
  3.     public Collection findAll();  
  4.     public void updateItem(Item item);  

ItemDao定義持久化操作的接口,用於隔離持久化代碼。

java 代碼
  1. public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport {  
  2.     public Item getItemById(Long id) {  
  3.         return (Item) getHibernateTemplate().load(Item.class, id);  
  4.     }  
  5.     public Collection findAll() {  
  6.         return (List) getHibernateTemplate().find("from Item");  
  7.     }  
  8.     public void updateItem(Item item) {  
  9.         getHibernateTemplate().update(item);  
  10.     }  

java 代碼
  1. public class ItemManager {   
  2.     private ItemDao itemDao;   
  3.     public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao;}   
  4.     public Bid loadItemById(Long id) {   
  5.         itemDao.loadItemById(id);   
  6.     }   
  7.     public Collection listAllItems() {   
  8.         return  itemDao.findAll();   
  9.     }   
  10.     public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount,   
  11.                             Bid currentMaxBid, Bid currentMinBid) throws BusinessException {   
  12.         item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid);  
  13.         itemDao.update(item);    // 必須顯式的調用DAO,保持持久化  
  14.     }  

<script>render_code();</script>

在第二種模型中,placeBid業務邏輯是放在Item中實現的,而loadItemById和findAll業務邏輯是放在ItemManager中實現的。不過值得注意的是,即使placeBid業務邏輯放在Item中,你仍然需要在ItemManager中簡單的封裝一層,以保證對placeBid業務邏輯進行事務的管理和持久化的觸發。

這種模型是Martin Fowler所指的真正的domain model。在這種模型中,有三個業務邏輯方法:placeBid,loadItemById和findAll,現在的問題是哪個邏輯應該放在Item中,哪個邏輯應該放在ItemManager中。在我們這個例子中,placeBid放在Item中(但是ItemManager也需要對它進行簡單的封裝),loadItemById和findAll是放在ItemManager中的。

切分的原則是什麼呢? Rod Johnson提出原則是“case by case”,可重用度高的,和domain object狀態密切關聯的放在Item中,可重用度低的,和domain object狀態沒有密切關聯的放在ItemManager中。

我提出的原則是:看業務方法是否顯式的依賴持久化。

Item的placeBid這個業務邏輯方法沒有顯式的對持久化ItemDao接口產生依賴,所以要放在Item中。請注意,如果脫離了Hibernate這個持久化框架,Item這個domain object是可以進行單元測試的,他不依賴於Hibernate的持久化機制。它是一個獨立的,可移植的,完整的,自包含的域對象

而loadItemById和findAll這兩個業務邏輯方法是必須顯式的對持久化ItemDao接口產生依賴,否則這個業務邏輯就無法完成。如果你要把這兩個方法放在Item中,那麼Item就無法脫離Hibernate框架,無法在Hibernate框架之外獨立存在。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章