Maison  >  Article  >  développement back-end  >  PHP设计模式之装饰器模式

PHP设计模式之装饰器模式

高洛峰
高洛峰original
2016-11-21 15:13:031102parcourir

概念

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

UML图

t0128f824aa7ed65fdd.png

角色

抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这些对象动态地添加职责。

具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。可以给这个类的对象添加一些职责

抽象装饰器(Decorator):维持一个指向构件Component对象的实例,并定义一个与抽象组件角色Component接口一致的接口

具体装饰器角色(ConcreteDecorator):向组件添加职责。

适用场景

需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

代码

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

/**
 * 装饰器模式
 */

/**
 * 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(&#39;张三&#39;);
        $lisi     = new Person(&#39;李四&#39;);

        $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恤 裤子 装扮者:李四


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn