重學設計模式 - Decorator模式

1、     Decorator模式簡介

  《設計模式》一書中對Decorator模式的意圖是這樣敘述的:

動態的給一個對象添加一些額外的職責。就增加功能來說,Decorator模式比生成子類更爲靈活。

  Decorator模式的工作原理是:可以創建始於Decorator對象(負責新功能的對象)終於原對象的一個對象“鏈”。實現方法:將原對象作爲新對象的成員。

  如上圖中Decorator模式的類圖隱含了一條對象鏈。每條鏈都始於一個Component對象(ConcreteComponentDecorator)。每個Decorator對象後面都跟着另一個Decorator對象或原ConcreteComponent對象。對象鏈總是終於一個ConcreteComponent對象。

  例如,在上圖中,ConcreteDecoratorB對象執行其Operation方法,然後調用Decorator類的Operation方法。這又將調用ConcreteDecoratorB對象之後的Component對象的Operation方法。

上圖爲設置表頭和頁腳的Decorator模式類圖,如果需要這樣的一張票據:

Header1

Header2

Sales Ticket

Footer1

則實現代碼:

Component * pComponent = new Header1(newHeader2(new Foorer1(new SalesTicket())));

pComponent->prtTicket();

2、     Decorator模式關鍵特徵

 

意圖

動態地給一個對象添加職責

問題

要使用的對象將執行所需基本功能。但是,可能需要爲這個對象將添加某些功能,這些附加功能可能發生在對象的基礎功能之前或之後。

解決方案

可以無需創建子類,而擴展一個對象的功能

參與者與協作者

ConcreteComponentDecorator對象爲自己添加功能。有時候用ConcreteComponent的派生類提供核心功能,在這種情況下ConcreteComponent類就不再是具體的,而是抽象的。Component類定義了所有這些類所使用的接口。

效果

所添加的功能放在小對象中。好處是可以在ConcreteComponent對象功能之前或之後動態添加功能。注意,雖然裝飾對象可以在被裝飾對象之前或之後添加功能,但對象鏈總是終於ConcreteComponent對象。

實現

創建一個抽象類來表示原類和要添加到這個類的功能。在裝飾類中,將對新功能的調用放在對緊隨其後對象的調用之前或之後,以獲得正確的順序。

 

3、     Decorator模式的本質

 

  Decorator模式的使用場合是:各種可選功能在另一個肯定要執行的功能之前或之後執行。

  上述Decorator模式的實現實際上是一種很糟糕的設計。例如,假設這些“裝飾對象”(即可選功能)是由不同的開發組開發的,而且系統可能拋出一些異常,需要由每個裝飾對象進行處理。理想情況下,可以相信這些開發組都能夠按預期地實現正確地捕獲這些異常。然而,如果他們沒有做到會怎麼樣呢?如果一個異常拋出了,而某個開發組編寫的代碼無法捕獲它,整個系統這時可能crash

  另一種方案是讓客戶對象捕獲異常。但是,這也就喪失了Decorator模式的價值,因爲客戶類需要完成比它以前更多的任務。

  更健全的解決方案是實現一個與ConcreteComponent對象接口相同的對象集合。它調用裝飾對象,捕獲後者沒有捕獲的任何必須捕獲的異常。事實上,這可能具有附加的好處:裝飾對象再也不必要與ConcreteComponent對象接口相同了。

  關鍵在於,Decorator模式有如下約束因素:

  • 存在幾種可選功能;
  • 這些裝飾對像可能遵循也可能不遵循所有規則;
  • 需要某種方式以所需的不同順序調用這些裝飾對象,但是又不能加重客戶對象的負擔;
  • 不希望應用程序必須承擔知道使用哪些裝飾對象(甚或是否存在)的職責。

這樣思考Decorator模式將使模式的意圖和實現分離開來。

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