Skip to content

装饰器也称为包装器模式是一种结构型模式与适配器模式多少有些相似,不同的是装饰器模式是对一个已有的结构增加"装饰",而适配器模式模式是为现有结构增加一个适配器类,用来处理互不兼容的类,而装饰器模式是向现有对象增加新的对象。当你想为一个类增加新的功能而不影响原有的功能时这时你就可以考虑使用装饰器模式了

php
//具体组件抽象类父类
abstract Class Component
{
    protected $site;

    abstract public function getSite();

    abstract public function getPrice();
}

//装饰器参与者
abstract Class Decorator extends Component
{
    public function getSite()
    {

    }

    public function getPrice()
    {

    }
}

class BasicSite extends Component
{
    public function __construct()
    {
        $this->site = "basic Site";
    }

    public function getSite()
    {
        return $this->site;
    }

    public function getPrice()
    {
        return 200;
    }
}

class Maintenance extends Decorator
{
    public function __construct(Component $site)
    {
        $this->site = $site;
    }

    public function getSite()
    {
        return $this->site->getSite();
    }

    public function getPrice()
    {
        return 90 + $this->site->getPrice();
    }
}

class Video extends Component
{
    public function __construct(Component $site)
    {
        $this->site = $site;
    }

    public function getSite()
    {
        return $this->site->getSite() . ' from Video';
    }

    public function getPrice()
    {
        return 80 + $this->site->getPrice();
    }
}

class Database extends Component
{
    public function __construct(Component $site)
    {
        $this->site = $site;
    }

    public function getSite()
    {
        return $this->site->getSite() . ' from database';
    }

    public function getPrice()
    {
        return 80 + $this->site->getPrice();
    }
}

class Client
{
    private $basicSite;

    public function __construct()
    {
        $this->basicSite = new BasicSite();
        $this->basicSite = $this->warpComponent($this->basicSite());

        $site = $this->basicSite->getSite();
        $price = $this->basicSite->getPrice();
        echo $site . '--->' . $price;
    }

    private function warpComponent(Component $component)
    {
        $component = new Maintenance($component);
        $component = new Video($component);
        $component = new Database($component);
        return $component;

    }
}

new Client();

最后总结一下:从上边的例子我们不难看出除了自己所特有的属性和方法外,所有的具体组件和装饰器都包含相同的接口。类似于'接口'在计算机编程中,一般我们用到包装器(暂且将适配器模式和装饰器都称为包装器)是为了处理接口的不兼容或者希望为组件增加新的功能。从某种程度上说包装器就是为了减少不兼容的一种策略。