PHP設計模式之裝飾器模式

PHP設計模式之裝飾器模式

裝飾器模式解決的問題

修飾模式,是面向對象編程領域中,一種動態地往一個類中添加新的行爲的設計模式。就功能而言,修飾模式相比生成子類更爲靈活,這樣可以給某個對象而不是整個類添加一些功能。

將所有的功能建立在繼承體系上會導致系統中的類越來越多,而且當你又要修改他們的分支的時候,可能還會出現重複代碼

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

// 區域抽象類
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

總結
上面的調用方法很像建立了一個管道,裝飾器模式經常被用於創建過濾器。

可以看到,這樣的模型很具有擴者性,我們可以輕鬆的添加其他裝飾器給區域對象,且不需要更改其他類。


注意:博客轉載至:https://segmentfault.com/a/1190000004467783

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