首頁 >後端開發 >php教程 >php物件導向進階設計模式:裝飾器模式

php物件導向進階設計模式:裝飾器模式

巴扎黑
巴扎黑原創
2017-05-22 09:48:501762瀏覽

什麼是裝飾模式?

如果對已有物件的部分內或功能性發生改變,但是不需要修改原始物件的結構,那麼使用裝飾器設計模式最適合。

裝飾器模式應用問題與解決方案:

我們最開始學習物件導向程式設計的相關知識時,第一個障礙往往是理解繼承當中的父子關係。隨著時間的推移,我們會更加熟悉這種程式方法。當面對新的挑戰時,經驗豐富的物件導向程式設計人員會立即為某個物件擴展更多的功能。不過,正如萬物皆有度,只有適度的使用才能確保這種工作的良好發展。

程式碼庫應對類別層次的數量有限制。如果物件開始要求啟用過多的子類,那麼對應的程式碼就會犧牲程式設計師的理解力和可維護性。通常,我竭力保證用於一個對象的父子關係不超過3個。我發現:只要創建較多的父子關係,那麼程式碼就會變得混亂和難以控制。除此之外,使用一般的紙張也無法答應出應用程式中任何物件的UML圖表示。

不過,我並不希望阻止類別擴充的使用。實際上,我們經常使用適當的解決方案來擴展物件。但是,對於某些問題來說,使用基於裝飾器設計模式的類別是更好的解決方案。

裝飾器設計模式適用於程式設計人員話費大量時間所處的下列工作場合:變更是快速且細小的,幾乎不影響應用程式的其餘部分。使用裝飾器設計模式設計類別的目標是:不必重寫任何現有的功能性,而是對某個基底物件套用增量變更。裝飾器採用這樣的建構方式:在主程式碼流程中應能夠直接插入一個或多個變更或「裝飾」目標物件的裝飾器,同時不影響其他程式碼流。

UML

下UML圖詳細說明了一個使用裝飾器設計模式的類別設計。

php物件導向進階設計模式:裝飾器模式

下面對上圖的說明:

1.MyObject是具有現有功能性的基底類別。這個類別包含名為items的公共陣列和名為show ItemsFormatted()的公共方法。

2.show ItemsFormatted()方法負責接受items數組,並且使用預先定義的功能性格式化該數組後提交輸出。

3.MyObjectDecorator類別包含MyObject的一個私人實例和兩個公用方法:MyObjectDecorator()和decorateItems()。

4.MyObjectDecorator()方法代表建構函數,它接受一個MyObject類型參數並將其儲存在內部。

5.decorateItems()方法可修改MyObject實例的items陣列。

我們來看下面這個例子,為了計算一塊區域的價值,我們把程式碼寫成下面這個樣子:

// 区域抽象类
abstract class Area
{
    abstract public function treasure();
}
//森林类,价值100
class Forest extends Area 
{
    public function treasure()
    {
        return 100;
    }
}
//沙漠类,价值10
class Desert extends Area
{
    function function treasure()
    {
        return 10;
    }
}

上面的程式碼看起來好像沒有什麼問題,但是如果需要給一片被破壞的森林運算價值怎麼辦呢,加上DamageForest子類別麼?顯然是不可行的,因為很有可能還有其他很多類型疊加的類,這會導致類別中可能會有重複的程式碼,而子類別也會變的越來越多。

裝飾器模式使用組合和委託,而不是使用繼承來解決上述的問題,我們在來看下面改良過的程式碼:

// 区域抽象类
abstract class Area
{    
   abstract public function treasure();
}

//森林类,价值100
class Forest extends Area 
{
   public function treasure()
   {
       return 100;
   }
}
//沙漠类,价值10
class Desert extends Area
{
   function function treasure()
   {
       return 10;
   }
}
//区域类的装饰器类
abstract class AreaDecorateor extends Area
{
   protected $_area = null;

   public function __construct(Area $area)
   {
       $this->_area = $area;
   }
}

//被破坏了后的区域,价值只有之前的一半
class Damaged extends AreaDecorateor
{
   public function treasure()
   {
       return $this->_area->treasure() * 0.5;
   }
}

//现在我们来获取被破坏的森林类的价值
$damageForest = new Damaged(new Forest());
echo $damageForest->treasure();  //返回50

以上是php物件導向進階設計模式:裝飾器模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn