PHP設計模式之裝飾器模式

概念

裝飾器模式(Decorator Pattern)容許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是做爲現有的類的一個包裝。php

這種模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。html

UML圖

clipboard.png

角色

  1. 抽象組件角色(Component):定義一個對象接口,以規範準備接受附加責任的對象,便可以給這些對象動態地添加職責。設計模式

  2. 具體組件角色(ConcreteComponent) :被裝飾者,定義一個將要被裝飾增長功能的類。能夠給這個類的對象添加一些職責測試

  3. 抽象裝飾器(Decorator):維持一個指向構件Component對象的實例,並定義一個與抽象組件角色Component接口一致的接口this

  4. 具體裝飾器角色(ConcreteDecorator):向組件添加職責。spa

適用場景

  1. 須要動態的給一個對象添加功能,這些功能能夠再動態的撤銷。設計

  2. 須要增長由一些基本功能的排列組合而產生的很是大量的功能,從而使繼承關係變的不現實。code

  3. 當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。component

代碼

代碼:htm

<?php
header('Content-type:text/html;charset=utf-8');

/**
 * 裝飾器模式
 */

/**
 * Interface IComponent 組件對象接口
 */
interface IComponent
{
    public function display();
}

/**
 * Class Person 待裝飾對象
 */
class Person implements IComponent
{
    private $_name;

    /**
     * Person constructor. 構造方法
     *
     * @param $name 對象人物名稱
     */
    public function __construct($name)
    {
        $this->_name = $name;
    }

    /**
     * 實現接口方法
     */
    public function display()
    {
        echo "裝扮者:{$this->_name}<br/>";
    }
}

/**
 * Class Clothes 全部裝飾器父類-服裝類
 */
class Clothes implements IComponent
{
    protected $component;

    /**
     * 接收裝飾對象
     *
     * @param IComponent $component
     */
    public function decorate(IComponent $component)
    {
        $this->component = $component;
    }

    /**
     * 輸出
     */
    public function display()
    {
        if(!empty($this->component))
        {
            $this->component->display();
        }
    }

}


/**
 * 下面爲具體裝飾器類
 */

/**
 * Class Sneaker 運動鞋
 */
class Sneaker extends Clothes
{
    public function display()
    {
        echo "運動鞋  ";
        parent::display();
    }
}

/**
 * Class Tshirt T恤
 */
class Tshirt extends Clothes
{
    public function display()
    {
        echo "T恤  ";
        parent::display();
    }
}

/**
 * Class Coat 外套
 */
class Coat extends Clothes
{
    public function display()
    {
        echo "外套  ";
        parent::display();
    }
}

/**
 * Class Trousers 褲子
 */
class Trousers extends Clothes
{
    public function display()
    {
        echo "褲子  ";
        parent::display();
    }
}


/**
 * 客戶端測試代碼
 */
class Client
{
    public static function test()
    {
        $zhangsan = new Person('張三');
        $lisi     = new Person('李四');

        $sneaker  = new Sneaker();
        $coat     = new Coat();

        $sneaker->decorate($zhangsan);
        $coat->decorate($sneaker);
        $coat->display();

        echo "<hr/>";

        $trousers = new Trousers();
        $tshirt   = new Tshirt();

        $trousers->decorate($lisi);
        $tshirt->decorate($trousers);
        $tshirt->display();
    }
}

Client::test();

運行結果:

外套 運動鞋 裝扮者:張三
T恤 褲子 裝扮者:李四
相關文章
相關標籤/搜索