您的位置:首页 > 其它

10.装饰器模式

2016-03-05 23:56 344 查看


传统方法:

//传统方法,继承并重写
class Canvas2 extends IMooc\Canvas
{
public function draw()
{
echo "<div style='color:red;'>";
parent::draw();
echo "</div>";
}
}

$canvas1 = new Canvas2();
$canvas1->init();
$canvas1->rect(3,6,4,12);
$canvas1->draw();


装饰器模式:

index.php

<?php

define('BASEDIR',__DIR__);

include BASEDIR . '/IMooc/Loader.php';
spl_autoload_register('\\IMooc\\Loader::autoload');

$canvas1 = new IMooc\Canvas();
$canvas1->init();
$canvas1->addDecorator(new \IMooc\ColorDrawDecorator('blue'));
$canvas1->addDecorator(new \IMooc\SizeDrawDecorator('100px'));
$canvas1->rect(3,6,4,12);
$canvas1->draw();


DrawDecorator.php

<?php

namespace IMooc;

// 1.先声明一个装饰器的接口
interface DrawDecorator
{
//在这个方法之前,之后加一些额外的能力
public function beforeDraw();
public 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;
}

//3. 动态的增加装饰器对象
function addDecorator(DrawDecorator $decorator)
{
$this->decorators[] = $decorator;
}

//4.添加两个调用装饰器的方法
function beforeDraw()
{
//逐个调用每个装饰器提供的方法
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}
//5.添加两个调用装饰器的方法
function afterDraw()
{
//装饰器反转,before 是先进先出,after 是后进先出
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}

function draw()
{
// 2. 在渲染画布之前,装饰器方法调用
$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;

//6.实现装饰器对象,颜色装饰器,用来修改画布的颜色,必须实现装饰器接口

class ColorDrawDecorator implements DrawDecorator
{
protected $color;

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

public function beforeDraw()
{
echo "<div style='color:{$this->color};'";
}

public function afterDraw()
{
echo "</div>";
}
}


SizeDrawDecorator.php

<?php

namespace IMooc;

//7. 这个装饰器的作用是修改文字的大小
class SizeDrawDecorator implements DrawDecorator
{
protected $size;

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

public function beforeDraw()
{
echo "<div style='font-size:{$this->size};'";
}

public function afterDraw()
{
echo "</div>";
}
}


<?php

interface Component
{
public function operation();
}

class ConcreteComponent implements  Component
{
public function operation()
{
echo 'do operation <br/>';
}
}

abstract class Decorator implements Component
{
protected $component;

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

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

class ConcreteDecoratorA extends Decorator
{
public function __construct(Component $component)
{
parent::__construct($component);
}

public function operation()
{
parent::operation();
echo 'do Operation AAA<br/>';
}
}

class ConcreteDecoratorB extends Decorator
{
public function __construct(Component $component)
{
parent::__construct($component);
}

public function operation()
{
parent::operation();
echo 'do Operation BBB<br/>';
}
}

class Client
{
public static function main()
{
$decoratorA = new ConcreteDecoratorA(new ConcreteComponent());
$decoratorA->operation();
echo '<hr/>';
$decoratorB = new ConcreteDecoratorB($decoratorA);
$decoratorB->operation();
}
}

Client::main();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: