亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

domain object模型探討(robbin原創(chuàng))

系統(tǒng) 1948 0

有興趣可看此處原文及相關(guān)討論: 總結(jié)一下最近關(guān)于domain object以及相關(guān)的討論

======================================

?

在最近的圍繞domain object的討論中浮現(xiàn)出來了三種模型,(還有一些其他的旁枝,不一一分析了),經(jīng)過一番討論,各種問題逐漸清晰起來,在這里我試圖做一個總結(jié),便于大家了解和掌握。

第一種模型:只有g(shù)etter/setter方法的純數(shù)據(jù)類,所有的業(yè)務(wù)邏輯完全由business object來完成(又稱TransactionScript),這種模型下的domain object被Martin Fowler稱之為“貧血的domain object”。下面用舉一個具體的代碼來說明,代碼來自Hibernate的caveatemptor,但經(jīng)過我的改寫:

一個實體類叫做Item,指的是一個拍賣項目
一個DAO接口類叫做ItemDao
一個DAO接口實現(xiàn)類叫做ItemDaoHibernateImpl
一個業(yè)務(wù)邏輯類叫做ItemManager(或者叫做ItemService)

Java代碼 復(fù)制代碼
  1. public ? class ?Item? implements ?Serializable?{??
  2. ???? private ?Long?id?=? null ;??
  3. ???? private ? int ?version;??
  4. ???? private ?String?name;??
  5. ???? private ?User?seller;??
  6. ???? private ?String?description;??
  7. ???? private ?MonetaryAmount?initialPrice;??
  8. ???? private ?MonetaryAmount?reservePrice;??
  9. ???? private ?Date?startDate;??
  10. ???? private ?Date?endDate;??
  11. ???? private ?Set?categorizedItems?=? new ?HashSet();??
  12. ???? private ?Collection?bids?=? new ?ArrayList();??
  13. ???? private ?Bid?successfulBid;??
  14. ???? private ?ItemState?state;??
  15. ???? private ?User?approvedBy;??
  16. ???? private ?Date?approvalDatetime;??
  17. ???? private ?Date?created?=? new ?Date();??
  18. ???? //??getter/setter方法省略不寫,避免篇幅太長 ??
  19. }??
    public class Item implements Serializable {
    private Long id = null;
    private int version;
    private String name;
    private User seller;
    private String description;
    private MonetaryAmount initialPrice;
    private MonetaryAmount reservePrice;
    private Date startDate;
    private Date endDate;
    private Set categorizedItems = new HashSet();
    private Collection bids = new ArrayList();
    private Bid successfulBid;
    private ItemState state;
    private User approvedBy;
    private Date approvalDatetime;
    private Date created = new Date();
    //  getter/setter方法省略不寫,避免篇幅太長
}
  

?

Java代碼 復(fù)制代碼
  1. public ? interface ?ItemDao?{??
  2. ???? public ?Item?getItemById(Long?id);??
  3. ???? public ?Collection?findAll();??
  4. ???? public ? void ?updateItem(Item?item);??
  5. }??
    public interface ItemDao {
    public Item getItemById(Long id);
    public Collection findAll();
    public void updateItem(Item item);
}
  



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

Java代碼 復(fù)制代碼
  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. ????}??
  11. }??
    public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport {
    public Item getItemById(Long id) {
        return (Item) getHibernateTemplate().load(Item.class, id);
    }
    public Collection findAll() {
        return (List) getHibernateTemplate().find("from Item");
    }
    public void updateItem(Item item) {
        getHibernateTemplate().update(item);
    }
}
  


ItemDaoHibernateImpl完成具體的持久化工作,請注意,數(shù)據(jù)庫資源的獲取和釋放是在ItemDaoHibernateImpl 里面處理的,每個DAO方法調(diào)用之前打開Session,DAO方法調(diào)用之后,關(guān)閉Session。(Session放在ThreadLocal中,保證 一次調(diào)用只打開關(guān)閉一次)

Java代碼 復(fù)制代碼
  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. ???????????? if ?(currentMaxBid?!=? null ?&&?currentMaxBid.getAmount().compareTo(bidAmount)?>? 0 )?{??
  13. ???????? throw ? new ?BusinessException( "Bid?too?low." );??
  14. ????}??
  15. ??????
  16. ???? //?Auction?is?active ??
  17. ???? if ?(?!state.equals(ItemState.ACTIVE)?)??
  18. ???????? throw ? new ?BusinessException( "Auction?is?not?active?yet." );??
  19. ??????
  20. ???? //?Auction?still?valid ??
  21. ???? if ?(?item.getEndDate().before(? new ?Date()?)?)??
  22. ???????? throw ? new ?BusinessException( "Can't?place?new?bid,?auction?already?ended." );??
  23. ??????
  24. ???? //?Create?new?Bid ??
  25. ????Bid?newBid?=? new ?Bid(bidAmount,?item,?bidder);??
  26. ??????
  27. ???? //?Place?bid?for?this?Item ??
  28. ????item.getBids().add(newBid);??
  29. ????itemDao.update(item);????? //??調(diào)用DAO完成持久化操作 ??
  30. ???? return ?newBid;??
  31. ????}??
  32. }??
    public class ItemManager {
    private ItemDao itemDao;
    public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao;}
    public Bid loadItemById(Long id) { 
        itemDao.loadItemById(id);
    }
    public Collection listAllItems() {
        return  itemDao.findAll();
    }
    public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount,
	                    Bid currentMaxBid, Bid currentMinBid) throws BusinessException {
            if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) {
    	throw new BusinessException("Bid too low.");
    }
    
    // Auction is active
    if ( !state.equals(ItemState.ACTIVE) )
    	throw new BusinessException("Auction is not active yet.");
    
    // Auction still valid
    if ( item.getEndDate().before( new Date() ) )
    	throw new BusinessException("Can't place new bid, auction already ended.");
    
    // Create new Bid
    Bid newBid = new Bid(bidAmount, item, bidder);
    
    // Place bid for this Item
    item.getBids().add(newBid);
    itemDao.update(item);     //  調(diào)用DAO完成持久化操作
    return newBid;
    }
}
  



事務(wù)的管理是在ItemManger這一層完成的,ItemManager實現(xiàn)具體的業(yè)務(wù)邏輯。除了常見的和CRUD有關(guān)的簡單邏輯之外,這里還有一個placeBid的邏輯,即項目的競標。

以上是一個完整的第一種模型的示例代碼。在這個示例中,placeBid,loadItemById,findAll等等業(yè)務(wù)邏輯統(tǒng)統(tǒng)放在ItemManager中實現(xiàn),而Item只有g(shù)etter/setter方法。

?

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

一個帶有業(yè)務(wù)邏輯的實體類,即domain object是Item
一個DAO接口ItemDao
一個DAO實現(xiàn)ItemDaoHibernateImpl
一個業(yè)務(wù)邏輯對象ItemManager

Java代碼 復(fù)制代碼
  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);?? //?請注意這一句,透明的進行了持久化,但是不能在這里調(diào)用ItemDao,Item不能對ItemDao產(chǎn)生依賴! ??
  25. ??????
  26. ???????? return ?newBid;??
  27. ????}??
  28. }??
    public class Item implements Serializable {
    //  所有的屬性和getter/setter方法同上,省略
    public Bid placeBid(User bidder, MonetaryAmount bidAmount,
                        Bid currentMaxBid, Bid currentMinBid)
    	throws BusinessException {
    
    	// Check highest bid (can also be a different Strategy (pattern))
    	if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) {
    		throw new BusinessException("Bid too low.");
    	}
    
    	// Auction is active
    	if ( !state.equals(ItemState.ACTIVE) )
    		throw new BusinessException("Auction is not active yet.");
    
    	// Auction still valid
    	if ( this.getEndDate().before( new Date() ) )
    		throw new BusinessException("Can't place new bid, auction already ended.");
    
    	// Create new Bid
    	Bid newBid = new Bid(bidAmount, this, bidder);
    
    	// Place bid for this Item
    	this.getBids.add(newBid);  // 請注意這一句,透明的進行了持久化,但是不能在這里調(diào)用ItemDao,Item不能對ItemDao產(chǎn)生依賴!
    
    	return newBid;
    }
}
  



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

ItemDao和ItemDaoHibernateImpl的代碼同上,省略。

Java代碼 復(fù)制代碼
  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);???? //?必須顯式的調(diào)用DAO,保持持久化 ??
  14. ????}??
  15. }??
    public class ItemManager { 
    private ItemDao itemDao; 
    public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao;} 
    public Bid loadItemById(Long id) { 
        itemDao.loadItemById(id); 
    } 
    public Collection listAllItems() { 
        return  itemDao.findAll(); 
    } 
    public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount, 
                            Bid currentMaxBid, Bid currentMinBid) throws BusinessException { 
        item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid);
        itemDao.update(item);    // 必須顯式的調(diào)用DAO,保持持久化
    }
}
  



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

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

切分的原則是什么呢? Rod Johnson提出原則是“case by case”,可重用度高的,和domain object狀態(tài)密切關(guān)聯(lián)的放在Item中,可重用度低的,和domain object狀態(tài)沒有密切關(guān)聯(lián)的放在ItemManager中。

我提出的原則是:看業(yè)務(wù)方法是否顯式的依賴持久化。

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

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

?

第三種模型印象中好像是firebody或者是Archie提出的(也有可能不是,記不清楚了),簡單的來說,這種模型就是把第二種模型的domain object和business object合二為一了。所以ItemManager就不需要了,在這種模型下面,只有三個類,他們分別是:

Item:包含了實體類信息,也包含了所有的業(yè)務(wù)邏輯
ItemDao:持久化DAO接口類
ItemDaoHibernateImpl:DAO接口的實現(xiàn)類

由于ItemDao和ItemDaoHibernateImpl和上面完全相同,就省略了。

Java代碼 復(fù)制代碼
  1. public ? class ?Item? implements ?Serializable?{??
  2. ???? //??所有的屬性和getter/setter方法都省略 ??
  3. ??? private ? static ?ItemDao?itemDao;??
  4. ???? public ? void ?setItemDao(ItemDao?itemDao)?{ this .itemDao?=?itemDao;}??
  5. ??????
  6. ???? public ? static ?Item?loadItemById(Long?id)?{??
  7. ???????? return ?(Item)?itemDao.loadItemById(id);??
  8. ????}??
  9. ???? public ? static ?Collection?findAll()?{??
  10. ???????? return ?(List)?itemDao.findAll();??
  11. ????}??
  12. ??
  13. ???? public ?Bid?placeBid(User?bidder,?MonetaryAmount?bidAmount,??
  14. ????????????????????Bid?currentMaxBid,?Bid?currentMinBid)??
  15. ???? throws ?BusinessException?{??
  16. ??????
  17. ???????? //?Check?highest?bid?(can?also?be?a?different?Strategy?(pattern)) ??
  18. ???????? if ?(currentMaxBid?!=? null ?&&?currentMaxBid.getAmount().compareTo(bidAmount)?>? 0 )?{??
  19. ???????????? throw ? new ?BusinessException( "Bid?too?low." );??
  20. ????????}??
  21. ??????????
  22. ???????? //?Auction?is?active ??
  23. ???????? if ?(?!state.equals(ItemState.ACTIVE)?)??
  24. ???????????? throw ? new ?BusinessException( "Auction?is?not?active?yet." );??
  25. ??????????
  26. ???????? //?Auction?still?valid ??
  27. ???????? if ?(? this .getEndDate().before(? new ?Date()?)?)??
  28. ???????????? throw ? new ?BusinessException( "Can't?place?new?bid,?auction?already?ended." );??
  29. ??????????
  30. ???????? //?Create?new?Bid ??
  31. ????????Bid?newBid?=? new ?Bid(bidAmount,? this ,?bidder);??
  32. ??????????
  33. ???????? //?Place?bid?for?this?Item ??
  34. ???????? this .addBid(newBid);??
  35. ????????itemDao.update( this );?????? //??調(diào)用DAO進行顯式持久化 ??
  36. ???????? return ?newBid;??
  37. ????}??
  38. }??
    public class Item implements Serializable {
    //  所有的屬性和getter/setter方法都省略
   private static ItemDao itemDao;
    public void setItemDao(ItemDao itemDao) {this.itemDao = itemDao;}
    
    public static Item loadItemById(Long id) {
        return (Item) itemDao.loadItemById(id);
    }
    public static Collection findAll() {
        return (List) itemDao.findAll();
    }

    public Bid placeBid(User bidder, MonetaryAmount bidAmount,
                    Bid currentMaxBid, Bid currentMinBid)
    throws BusinessException {
    
        // Check highest bid (can also be a different Strategy (pattern))
        if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) {
        	throw new BusinessException("Bid too low.");
        }
        
        // Auction is active
        if ( !state.equals(ItemState.ACTIVE) )
        	throw new BusinessException("Auction is not active yet.");
        
        // Auction still valid
        if ( this.getEndDate().before( new Date() ) )
        	throw new BusinessException("Can't place new bid, auction already ended.");
        
        // Create new Bid
        Bid newBid = new Bid(bidAmount, this, bidder);
        
        // Place bid for this Item
        this.addBid(newBid);
        itemDao.update(this);      //  調(diào)用DAO進行顯式持久化
        return newBid;
    }
}
  



在這種模型中,所有的業(yè)務(wù)邏輯全部都在Item中,事務(wù)管理也在Item中實現(xiàn)。

?

?

轉(zhuǎn)自:http://www.iteye.com/topic/11712

?

domain object模型探討(robbin原創(chuàng))


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品久久久久久亚洲精品 | 亚洲美女视频网 | 久久99青青久久99久久 | 精品免费久久久久久久 | 看欧美毛片一级毛片 | 久久亚洲精选 | 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲精品福利一区二区三区 | 成人a毛片视频免费看 | 九九99re在线视频精品免费 | 性欧美精品久久久久久久 | 欧美日韩国产综合一区二区三区 | 成人交性视频免费看 | 久久天天躁狠狠躁狠狠躁 | 欧美一级毛片免费看高清 | 免费网站看v片在线成人国产系列 | 台湾佬中文娱乐2222vvv | 99久久免费国内精品 | 四虎精品影院永久在线播放 | 999久久66久6只有精品 | 日产国产精品久久久久久 | 毛片免费永久不卡视频观看 | 久久综合99re88久久爱 | 亚洲欧美综合网站 | 不卡中文字幕在线观看 | 国产乱肥老妇精品视频 | 亚洲国产日韩综合久久精品 | 国产妇乱子伦视频免费 | 伊人国产在线播放 | 国产精品天天影视久久综合网 | 天天干夜夜爽天天操夜夜爽视频 | 日日射天天操 | 2022国产91精品久久久久久 | 国产精品久久二区三区色裕 | 国产欧美亚洲三区久在线观看 | 亚洲国产天堂 | 黄 色 免 费 网站在线观看 | 久久精品国产亚洲网站 | 亚洲国产婷婷综合在线精品 | 国产美女免费国产 | 欧美日本免费观看αv片 |