使用场景: 当某一功能或方法draw,要满足不同的功能需求时,可以使用装饰器模式;实现方式:在方法的类中建addDecorator(添加装饰器),beforeDraw,afterDraw 3个新方法, 后2个分别放置在要修改的方法draw首尾.然后创建不同的装器类(其中要包含相同的,beforeDraw,afterDraw方法)能过addDecorator添加进去,然后在beforeDraw,afterDraw中循环处理,与观察者模式使用有点相似
1.装饰器模式(Decorator),可以动态地添加修改类的功能
2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法
3.使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
DrawDecorator.php
<?php
namespace IMooc;
interface DrawDecorator
{
function beforeDraw();
function afterDraw();
}
Canvas.php
<?php
namespace IMooc;
class Canvas
{
public $data;
protected $decorators = array();
//Decorator
function init($width = 20, $height = 10)
{
$data = array();
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()
{
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}
function afterDraw()
{
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}
function draw()
{
$this->beforeDraw();
foreach($this->data as $line)
{
foreach($line as $char)
{
echo $char;
}
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 => $char)
{
if ($k2 < $b1 or $k2 > $b2) continue;
$this->data[$k1][$k2] = ' ';
}
}
}
}
ColorDrawDecorator.php
<?php
namespace IMooc;
class ColorDrawDecorator implements DrawDecorator
{
protected $color;
function __construct($color = 'red')
{
$this->color = $color;
}
function beforeDraw()
{
echo "<div style='color: {$this->color};'>";
}
function afterDraw()
{
echo "</div>";
}
}
index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR.'/IMooc/Loader.php';
spl_autoload_register('\\IMooc\\Loader::autoload');
$canvas = new IMooc\Canvas();
$canvas->init();
$canvas->addDecorator(new \IMooc\ColorDrawDecorator('green'));
$canvas->rect(3,6,4,12);
$canvas->draw();
评论