本次代码符合PHP规范PRS_0,根目录下新建一个Frame的目录(核心目录),建立APP目录(项目目录),统一访问入口文件index.php,建立类文件Loader.php(用于自动加载类)
index.php 公共部分
<?php
define('BASEDIR',__DIR__);
include BASEDIR.'/Frame/Loader.php';
spl_autoload_register('\\Frame\\Loader::autoload');
Loader.php
<?php
namespace Frame;
class Loader
{
static function autoload($class)
{
require BASEDIR.'/'.str_replace('\\','/',$class).'.php';
}
}
装饰器模式
- 以原型模式中的画布为例,现在我要修改画布的颜色、大小等属性。
- 传统方法:如果我要给图案添加颜色和大小,我就要新建一个类重写父类方法。
- 如果有的只要改变颜色、有的只要修改大小、还有的颜色和大小都需要修改?这种方法实现起来就很麻烦了。
装饰器模式特点:
- 装饰器模式,可以动态地添加修改类的功能。
- 一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法
- 使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
新建一个DrawDecorator.php接口文件用于约束画布的前置和后置
<?php
namespace Frame;
interface DrawDecorator
{
public function beforeDraw();
public function afterDraw();
}
新建ColorDrawDecorator.php用于颜色渲染的装饰器类,新建SizeDrawDecorator.php用于大小渲染的装饰器类。
<?php
namespace Frame;
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>";
}
}
<?php
namespace Frame;
class SizeDrawDecorator implements DrawDecorator
{
protected $size;
function __construct($size = '14px')
{
$this->size = $size;
}
function beforeDraw()
{
echo "<div style='font-size: {$this->size};'>";
}
function afterDraw()
{
echo "</div>";
}
}
我们把Canvas.php类文件修改一下,在画布渲染前加上前置操作,在画布渲染后加上后置操作,增加用于添加装饰器、执行前置和后置的方法。
<?php
namespace Frame;
class Canvas
{
public $data;
protected $decorators = array();
//Decorator
public 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;
}
/**
* 添加装饰器对象
* @param DrawDecorator $decorator
*/
public function addDecorator(DrawDecorator $decorator)
{
$this->decorators[] = $decorator;
}
//执行装饰器前置操作 先进先出原则
public function beforeDraw()
{
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}
//先进后出
public function afterDraw()
{
//执行装饰器后置操作 先进后出原则
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}
//渲染
public function draw()
{
$this->beforeDraw();//渲染前
foreach($this->data as $line)
{
foreach($line as $char)
{
echo $char;
}
echo "<br />\n";
}
$this->afterDraw();//渲染后
}
//设置图形的位置
public 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] = ' ';
}
}
}
}
在index.php中调用
<?php
//继承画布类
class Canvas2 extends Frame\Canvas
{
public function draw()
{
echo "<div style='color: red;'>";
parent::draw();
echo "</div>";
}
}
$canvas1 = new Canvas2();
$canvas1->init();
$canvas1->addDecorator(new \Frame\ColorDrawDecorator('green'));
$canvas1->addDecorator(new \Frame\SizeDrawDecorator('20px'));
$canvas1->rect(2,6,4,12);
$canvas1->draw();
One comment
PHP设计模式装饰器模式
1. 装饰器模式( Decorator ) ,可以动态地添加修改类的功能
2. - 个类提供了- -项功能,如果要在修改并添加额外的功能,传统
的编程模式,需要写-个子类继承它,并重新实现类的方法3.使用装饰器模式 ,仅需在运行时添加一个装饰器对象即可实现,
可以实现最大的灵活性