PHP设计模式 装饰器模式

参考:

http://www.lai18.com/content/422503.htm

《PHP设计模式》作    者:(美)萨莱     译    者:梁志敏,蔡建


定义:

装饰者模式就是不修改原类代码和继承的情况下动态扩展类的功能。传统的编程模式都是子类继承父类实现方法重载,使用装饰器模式,只需添加一个新的装饰器对象,更加灵活,避免类数量和层次过多。
如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构,那么使用装饰器设计模式最适合。


使用场景:

变化是快速和细小的,而且几乎不影响应用程序的其余部分。

使用目标:
不必重写任何现有的功能,而是对某个及对象应用增量变化

为了在不修改对象结构的前提下对现有对象的内部或功能性稍加修改,就应当使用装饰器设计模式


代码案列:

<?php
//被装饰者基类
interface Component{
    public function operation();
}

//装饰者基类
abstract class Decorator implements Component{
    protected $component;
    public function __construct(Component $component){
        $this->component = $component;
    }

    public function operation(){
        $this->component->operation();
    }
}

//具体装饰者类
class ConcreteComponent implements Component{
    public function operation(){
        echo 'do operation'.PHP_EOL;
    }
}

//具体装饰类A
class ConcreteDecoratorA extends Decorator {
    public function __construct(Component $component) {
        parent::__construct($component);
    }

    public function operation() {
        parent::operation();
        $this->addedOperationA();   //  新增加的操作
    }

    public function addedOperationA() {
        echo 'Add Operation A '.PHP_EOL;
    }
}

//具体装饰类B
class ConcreteDecoratorB extends Decorator {
    public function __construct(Component $component) {
        parent::__construct($component);
    }

    public function operation() {
        parent::operation();
        $this->addedOperationB();
    }

    public function addedOperationB() {
        echo 'Add Operation B '.PHP_EOL;
    }
}
class Client {
    public static function main() {
        /*
        do operation
        Add Operation A
        */
        $decoratorA = new ConcreteDecoratorA(new ConcreteComponent());
        $decoratorA->operation();
        /*
        do operation
        Add Operation A
        Add Operation B  
        */
        $decoratorB = new ConcreteDecoratorB($decoratorA);
        $decoratorB->operation();
    }
}

Client::main();

/*
应用程序对光盘(CD)进行处理。应用程序必须须有为CD添加音轨的方法以及显示CD音轨列表的方式。客户指定应当采用当行并且每个音轨必须以音轨号为前缀的方式显示CD音轨列表。
*/
class CD{
    public $trackList;
    
    public function __construct(){
        $this->trackList = array();
    }
    
    public function addTrack($track){
        $this->trackList[] = $track;
    }
    
    public function getTrackList(){
        $output = '';
        foreach($this->track as $k=>$v){
            $output .= ($k+1) ."){$v}";
        }
        return $output;
    }
}
/*
需求发生改变
只针对输出实例,输出的每个音轨都需要采用大写形式。
*/

class CDTrackListDecoratorCaps{
    private $cd;
    public function __construct(CD $cd){
        $this->cd = $cd
    }
    
    public function makeCaps(){
        foreach($this->cd->trackList as & $track){
            $track = strtoupper($track);
        }
    }
}

你可能感兴趣的:(设计模式,装饰器)