php设计模式-装饰器模式

PHP装饰器模式

1、什么是装饰器模式?

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

简单来说就是可以动态的添加和修改类的功能

2、为什么要用装饰器模式?

如果一个类提供了一项功能,现在需要修改或者添加额外的功能,传统的编程模式是需要写个子类集成它,并重新实现类的方法。使用装饰模式仅需在运行时添加一个装饰器对象即可实现。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能中

3、装饰器模式的优点

  • 我们可以保证类的层次不会因过多而发生混乱。
  • 当我们需求的修改很小时,不用改变原有的数据结构。

3、示例代码

/**
 * @purpose: 原始绘制图形的类
 * Class Canvas
 */
class CanvasOld
{
    /**
     * @var array 存入待绘制的数据
     */
    public $data;

    /**
     * @purpose: 初始化的时候填入*
     * @param int $width 所绘图形的宽度
     * @param int $high 所绘图形的高度
     */
    public function init($width = 20, $high = 10)
    {
        for ($i = 0; $i < $width; $i++)
        {
            for($j = 0; $j < $high; $j++)
            {
                $this->data[$i][$j] = '*';
            }
        }
    }

    /**
     * @purpose: 绘制图形
     */
    public function draw()
    {
        foreach ($this->data as $line)
        {
            foreach($line as $char)
            {
                echo $char;
            }
            echo '</br>';
        }
    }
}

/**
 * @purpose: 装饰器接口类
 * Interface DrawDecorator
 */
interface DrawDecorator
{
    /**
     * @return mixed 开始绘制之前的方法
     */
    public function beforeDraw();

    /**
     * @return mixed 开始绘制之后的方法
     */
    public function afterDraw();
}

/**
 * @purpose: 颜色装饰器
 * Class ColoerDecorator
 */
class ColoerDecorator implements DrawDecorator
{
    /**
     * @var string 颜色
     */
    public $color;

    public function __construct($color = 'red')
    {
        $this->color = $color;
    }

    /**
     * @return mixed 开始绘制之前的方法
     */
    public function beforeDraw()
    {
        echo "<div style='color:{$this->color}' >";
    }

    /**
     * @return mixed 开始绘制之后的方法
     */
    public function afterDraw()
    {
        echo '</div>';
    }
}


/**
 * @purpose: 字体大小装饰器
 * Class FontSizeDecorator
 */
class FontSizeDecorator implements DrawDecorator
{
    /**
     * @var string 字体大小
     */
    public $fontSize;

    public function __construct($color = 'red')
    {
        $this->fontSize = $color;
    }

    /**
     * @return mixed 开始绘制之前的方法
     */
    public function beforeDraw()
    {
        echo "<div style='font-size:{$this->fontSize}' >";
    }

    /**
     * @return mixed 开始绘制之后的方法
     */
    public function afterDraw()
    {
        echo '</div>';
    }
}


/**
 * @purpose: 添加装饰器后绘制图形的类
 * Class Canvas
 */
class Canvas
{
    /**
     * @var array 存入待绘制的数据
     */
    public $data;

    /**
     * @var array 保存所添加装饰的对象数组
     */
    public $_decorators;

    /**
     * @purpose: 初始化的时候填入*
     * @param int $width 所绘图形的宽度
     * @param int $high 所绘图形的高度
     */
    public function init($width = 20, $high = 10)
    {
        for ($i = 0; $i < $width; $i++)
        {
            for($j = 0; $j < $high; $j++)
            {
                $this->data[$i][$j] = '*';
            }
        }
    }

    /**
     * @purpose: 绘制图形
     */
    public function draw()
    {
        $this->beforeDraw(); //调用装饰器

        foreach ($this->data as $line)
        {
            foreach($line as $char)
            {
                echo $char;
            }
            echo '</br>';
        }

        $this->afterDraw(); //调用装饰器
    }

    /**
     * @purpose: 添加装饰器
     * @param DrawDecorator $decorator
     */
    public function addDecorator(DrawDecorator $decorator)
    {
        $this->_decorators[] = $decorator;
    }

    /**
     * @purpose: 开始绘制之前
     */
    public function beforeDraw()
    {
        foreach ($this->_decorators as $decorator)
        {
            $decorator->beforeDraw();
        }
    }

    /**
     * @purpose: 开始绘制之后
     */
    public function afterDraw()
    {
        //afterDraw中需要反着调用。
        $decorators = array_reverse($this->_decorators);
        foreach ($decorators as $decorator)
        {
            $decorator->afterDraw();
        }
    }
}

$cavas = new Canvas();
$cavas->addDecorator(new ColoerDecorator());    //添加颜色装饰器
//$cavas->addDecorator(new FontSizeDecorator());  //一个类封装一类功能,可按需添加
$cavas->draw();

本文为袋鼠学习中的总结,如有转载请注明出处:https://www.cnblogs.com/chrdai/p/11184510.html

posted @ 2019-07-14 16:02  Chrdai  阅读(1184)  评论(1编辑  收藏  举报