装饰器模式
简单说,就是动态的添加类的功能。
一个类提供了一项功能,如果我们要在类中添加修改其他功能,我们通常采用继承的方法。创建一个子类继承这个类,重新实现类的方法。
在面向对象的设计中,而我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以实现最大的灵活性
- 我们需要一个装饰器接口
- 然后是一个被装饰对象
- 最后我们需要若干个装饰器(实现装饰器接口的具体类)
装饰器接口:
提供装饰通用的方法,装饰器通过实现接口,对装饰对象添加功能
interface decorator {
/*
接口中的方法
*/
function before_do();
function after_do();
}
被装饰对象
被装饰对象中包含装饰器的通用方法,并且提供添加装饰器的功能
require 'decorator.php';
class user {
private $decorate_arr = array();
/*
装饰对象的eat方法,此方法作为例子
*/
public function eat()
{
$this->before_do();
echo '开始吃饭<br/>';
$this->after_do();
}
/*
添加装饰器
*/
public function add_decorate(decorator $decorator)
{
$this->decorate_arr[] = $decorator;
}
/*
遍历装饰器,调用装饰器方法
*/
public function before_do()
{
foreach ($this->decorate_arr as $decorator)
{
$decorator->before_do();
}
}
/*
遍历装饰器,调用装饰器方法
*/
public function after_do()
{
foreach ($this->decorate_arr as $decorator)
{
$decorator->after_do();
}
}
}
创建具体的装饰器
具体的装饰器实现了装饰器接口
//装饰器1
class decorator1 implements decorator {
public function before_do()
{
echo '先去洗手<br/>';
}
public function after_do()
{
echo '吃饱了,是时候看一波球了<br/>';
}
}
//装饰器2
class decorator2 implements decorator {
public function before_do()
{
echo '洗完手然后擦一下<br/>';
}
public function after_do()
{
echo '都是真球,不错不错<br/>';
}
}
具体展示
//实例化被装饰对象
$user = new user();
//添加装饰器
$user->add_decorate(new decorator1());
$user->add_decorate(new decorator2());
//调用方法
$user->eat();
结果:
先去洗手
洗完手然后擦一下
开始吃饭
吃饱了,是时候看一波球了
都是真球,不错不错
何时使用装饰器模式?
- 需要在不影响其他对象的情况下,以动态、透明的方式给对象添加职责。
- 如果不适合使用子类来进行扩展的时候,可以考虑使用装饰器模式。