课程名称:大话PHP设计模式
课程章节:装饰器模式
课程讲师:Rango
课程内容:
装饰器模式可以做什么?
- 装饰器模式可以动态的修改类中方法的功能
为什么要使用装饰器模式?
试想如下场景,某个类产生了一些数据,现在要对这些数据做处理,但不修改这个类,我们就可以使用装饰器模式,给类添加装饰器相关的方法,即可实现
代码
该实例中的
Imooc\Loader.php
文件为框架加载文件,不是策略模式中的文件
-
代码目录结构
-
Imooc/AddNumDecorator.php
<?php
namespace Imooc;
// 这是具体实现的装饰器
class AddNumDecorator implements DataDecorator
{
// 这是具体实现的方法,此处模拟对数据进行加一
public function modify(&$data)
{
++$data;
}
}
- Imooc/Data.php
<?php
namespace Imooc;
use Imooc\DataDecorator;
class Data
{
protected $decorators = [];
public function getData() {
$data = 1;
$this->modifyDecorator($data);
return $data;
}
// 给当前类新增一个装饰器
public function addDecorator(DataDecorator $decorator) {
$this->decorators[] = $decorator;
}
// 调用所有当前类的装饰器
private function modifyDecorator(&$data) {
foreach ($this->decorators as $decorator) {
$decorator->modify($data);
}
}
}
- Imooc/DataDecorator.php
<?php
namespace Imooc;
// 这个类是Data类的装饰器的接口
interface DataDecorator
{
// 这是一个装饰器,可以根据项目的具体需求定义相应的装饰器
public function modify(&$data);
}
- Imooc/Loader.php
<?php
namespace Imooc;
class Loader
{
static public function autoload($class) {
require BASEDIR . '/' . str_replace('\\', '/', $class) . '.php';
}
}
- index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR . '/Imooc/Loader.php';
spl_autoload_register('\\Imooc\\Loader::autoload');
$obj1 = new \Imooc\Data();
// 这里添加一个装饰器进去
$obj1->addDecorator(new \Imooc\AddNumDecorator());
echo $obj1->getData();
// 输出:没有添加装饰器的时候,输出1;添加了装饰器之后,输出2;这里的装饰器模拟的是对数据进行加一
课程收获
复习装饰器模式的时候,感觉和观察者模式还是比较相似的,可能这些设计模式就是如此吧