php设计模式之装饰器模式

装饰器模式

允许向一个已有的对象动态添加新的功能,又不改变其结构,使用子类继承的方法去实现添加新功能,会不可避免的出现子类过多,继承链很长额情况.

目录结构

|decorator  #项目根目录
|--Think  #核心类库
|----Loder.php  #自动加载类
|----decorator.php  #装饰器接口
|----colorDecorator.php  #颜色装饰器
|----sizeDecorator.php  #字体大小装饰器
|----echoText.php  #被装饰者
|--index.php #单一的入口文件

代码实践

装饰器接口 Think/decorator.php

<?php
/**
 * 装饰器接口
 * Interface decorator
 * @package Think
 */
namespace Think;

interface decorator{
    public function beforeDraw();
    public function afterDraw();
}

颜色装饰器 Think/colorDecorator.php

<?php
/**
 * 颜色装饰器
 */
namespace Think;

class colorDecorator implements decorator{
    protected $color;
    public function __construct($color) {
        $this->color = $color;
    }

    public function beforeDraw() {
        echo "color decorator :{$this->color}\n";
    }

    public function afterDraw() {
        echo "end color decorator\n";
    }
}

字体大小装饰器 Think/sizeDecorator.php

<?php
/**
 * 字体大小装饰器
 */
namespace Think;

class sizeDecorator implements decorator{
    protected $size;

    public function __construct($size) {
        $this->size = $size;
    }

    public function beforeDraw() {
        echo "size decorator {$this->size}\n";
    }

    public function afterDraw() {
        echo "end size decorator\n";
    }
}

被装饰者 Think/echoText.php

<?php
/**
 * 被装饰者
 */
namespace Think;

class echoText {
    protected $decorator = array();  //存放装饰器

    //装饰方法
    public function index() {
        //调用装饰器前置操作
        $this->before();
        echo "你好,我是装饰器\n";
        //执行装饰器后置操作
        $this->after();
    }

    public function addDecorator(Decorator $decorator) {
        $this->decorator[] = $decorator;
    }

    //执行装饰器前置操作 先进先出
    public function before() {
        foreach ($this->decorator as $decorator){
            $decorator->beforeDraw();
        }
    }

    //执行装饰器后置操作 先进后出
    public function after() {
        $decorators = array_reverse($this->decorator);
        foreach ($decorators as $decorator){
            $decorator->afterDraw();
        }
    }
}

自动加载 Think/Loder.php

<?php
namespace Think;

class Loder{
    static function autoload($class){
        require BASEDIR . '/' .str_replace('\\','/',$class) . '.php';
    }
}

入口文件index.php

<?php
define('BASEDIR',__DIR__);
include BASEDIR . '/Think/Loder.php';
spl_autoload_register('\\Think\\Loder::autoload');

//实例化输出类
$echo = new \Think\echoText();
//增加装饰器
$echo->addDecorator(new \Think\colorDecorator('red'));
//增加装饰器
$echo->addDecorator(new \Think\sizeDecorator('12'));
//装饰方法
$echo->index();

上一篇 php设计模式之观察者模式
下一篇 php设计模式之建造者模式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容