动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
装饰模式的组成
Component抽象构件:一个接口或者是抽象类,就是定义最核心的对象,也就是最原始的对象;ConcreteComponent具体构件:是最核心、最原始、最基本的接口或抽象类的实现,要装饰的就是这个;Decorator装饰角色:一般是一个抽象类,用于实现接口或抽象方法,其中不一定有抽象的方法,但其属性里必然有一个private变量指向Component抽象构件;ConcreteDecorator具体装饰角色:把最核心、最原始、最基本的东西装饰成其他东西。装饰模式的优点
装饰类和被装饰类可以独立发展,而不会相互耦合;装饰模式是机场关系的一个替代方案;装饰模式可以动态地扩展一个实现类的功能。装饰模式的缺点
多层的装饰是比较复杂的,尽量减少装饰类的数量,以便降低系统的复杂度。
装饰模式的使用场景
需要扩展一个类的功能,或给一个类增加附加功能;需要动态地给一个对象增加功能,这些功能可以再动态地撤销;需要为一批的兄弟类进行改装或加装功能。 <?php /** * 装饰者模式 */ namespace pattern; interface Component { public function operate(); } class ConcreteComponent implements Component { public function operate() { echo 'Concrete Component operate' . PHP_EOL; } } abstract class Decorator implements Component { protected $component = null; public function __construct(Component $component) { $this->component = $component; } public function operate() { $this->component->operate(); } } class ConcreteDecoratorA extends Decorator { public function operate() { parent::operate(); $this->_addOperate(); } private function _addOperate() { echo 'Concrete Decorator A add operation' . PHP_EOL; } } class ConcreteDecoratorB extends Decorator { public function operate() { $this->_addOperate(); parent::operate(); } private function _addOperate() { echo 'Concrete Decorator B add operation' . PHP_EOL; } } $component = new ConcreteComponent(); $decorator_a = new ConcreteDecoratorA($component); $decorator_b = new ConcreteDecoratorB($component); $decorator_a->operate(); echo str_repeat('-', 20) . PHP_EOL; $decorator_b->operate(); $decorator_c = new ConcreteDecoratorB($decorator_b); echo str_repeat('=', 20) . PHP_EOL; $decorator_c->operate();输出:
Concrete Component operate Concrete Decorator A add operation -------------------- Concrete Decorator B add operation Concrete Component operate ==================== Concrete Decorator B add operation Concrete Decorator B add operation Concrete Component operate