- 不使用继承
- 动态扩展
- 不改变原有的类
装饰器模式
是一种结构型模式,它动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
装饰模式是以对客户透明的方式动态地给一个对象附加上更多的职责。这也就是说,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
主要角色
- 抽象构件(Component)角色:定义一个对象接口,以规范准备接收附加职责的对象,从而可以给这些对象动态地添加职责。
- 具体构件(Concrete Component)角色:定义一个将要接收附加职责的类。
- 装饰(Decorator)角色:持有一个指向Component对象的指针,并定义一个与Component接口一致的接口。
- 具体装饰(Concrete Decorator)角色:负责给构件对象增加附加的职责。
适用性
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 处理那些可以撤消的职责,即需要动态的给一个对象添加功能并且这些功能是可以动态的撤消的。
- 当不能彩生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
- 原始类接口 Component
- 原始类接口的具体实现类 Concrete Component
- 装饰器接口 Decorator
- 装饰器接口的具体实现 Concrete Decorator
示例2
//基类
abstract class Beverage()
{
private $description = 'Unknown Beverage';
public function getDescription()
{
return $description;
}
abstract public function double cost();
}
//实例1
class Espresso extends Beverage
{
public function __construction()
{
$this->description = "Espresso";
}
public function cost()
{
return 1.99;
}
}
//实例2
class HouseBlend extends Beverage
{
public function __construction()
{
$this->description = "HouseBlend";
}
public function cost()
{
return 0.89;
}
}
//装饰者接口
abstract class CondimentDecorator extends Beverage
{
protected $beverage;
public function __construct(Beverage $beverage)
{
$this->beverage = $beverage;
}
abstract public function getDescription();
}
//装饰者1
class Mocha extends CondimentDecorator
{
public function getDescription()
{
return $this->beverage->getDescription.", Mocha";
}
public function cost()
{
return .20 + $this->beverage->cost();
}
}
测试
$expressoWithMocha = new Mocha(new Espresso());
$expressoWithMocha->getDescription();
$expressoWithMocha->cost();