基本概念:
装饰器模式(Decorator)可以动态地添加修改类的功。
应用场景:
一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,是新增一个子类继承它,并重新实现类的方法。使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以最大化实现代码的灵活性。
本文代码是基于 《设计模式之原型模式》 一文实现。
定义装饰器接口类
interface DrawDecorator { function beforeDraw(); function afterDraw(); }
定义颜色装饰器类,并实现装饰器接口
class ColorDecorator implements DrawDecorator { protected $color; function __construct($color = 'red') { $this->color = $color; } function beforeDraw() { // TODO: Implement beforeDraw() method. echo "<div style='color:$this->color'>"; } function afterDraw() { // TODO: Implement afterDraw() method. echo "</div>"; } }
定义尺寸装饰器类,并实现装饰器接口
class SizeDecorator implements DrawDecorator { protected $size; function __construct($size = 'red') { $this->size = $size; } function beforeDraw() { // TODO: Implement beforeDraw() method. echo "<div style='font-size:$this->size'>"; } function afterDraw() { // TODO: Implement afterDraw() method. echo "</div>"; } }
接下来在canvas类中添加装饰器操作方法(这里只写两个 beforeDecorator 和 afterDecorator)
/** * 新建canvas类 * Class Canvas * @package Wecot */ class Canvas implements DrawDecorator { public $data; private $decorators; function init($width = 30, $height = 15) { $data = []; for ($i = 0; $i < $height; $i++) { for ($j = 0; $j < $width; $j++) { $data[$i][$j] = '*'; } } $this->data = $data; } function addDecorator(DrawDecorator $decorator) { $this->decorators[] = $decorator; } function beforeDraw() { // TODO: Implement beforeDraw() method. foreach ($this->decorators as $decorator){ $decorator->beforeDraw(); } } function afterDraw() { // TODO: Implement afterDraw() method. $decorators = array_reverse($this->decorators); foreach ($decorators as $decorator){ $decorator->beforeDraw(); } } function draw() { $this->beforeDraw(); foreach ($this->data as $heightArr) { foreach ($heightArr as $widthChar) { echo $widthChar; } // echo PHP_EOL; echo "<br>\n"; } $this->afterDraw(); } function rect($a1, $a2, $b1, $b2) { foreach ($this->data as $k1 => $line) { if ($k1 < $a1 or $k1 > $a2) continue; foreach ($line as $k2 => $widthChar) { if ($k2 < $b1 or $k2 > $b2) continue; //对数组中元素置空 // $this->data[$k1][$k2] = ' '; $this->data[$k1][$k2] = ' '; } } } }
装饰器调用执行:
$canvas = new \Wecot\Canvas(); $canvas->init(); //添加颜色装饰器 $canvas->addDecorator(new \Wecot\ColorDecorator('blue')); //添加尺寸装饰器 $canvas->addDecorator(new \Wecot\SizeDecorator(25)); $canvas->rect(3, 6,4,15); $canvas->draw();
以上,装饰器模式完全避免了程序的高度内聚,和多次集成重写的繁杂方式。使用装饰器模式可以基本实现无侵入式的实现需求。
转载请注明:微刻 blog.wecot.cn » 设计模式之装饰器模式