PHP設計模式之裝飾器模式

裝飾器模式解決的問題

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

將全部的功能創建在繼承體系上會致使系統中的類愈來愈多,並且當你又要修改他們的分支的時候,可能還會出現重複代碼設計模式

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

// 區域抽象類
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子類麼?顯然是不可行的,由於頗有可能還有其餘不少類型疊加的類,這會致使類中可能會有重複的代碼,且子類也會變的愈來愈多。設計

裝飾器模式的實現

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

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

總結

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

能夠看到,這樣的模型很具備擴者性,咱們能夠輕鬆的添加其餘裝飾器給區域對象,且不須要更改其餘類,對象

相關文章
相關標籤/搜索