概述:动态地给一个工具添加一些额外的职责,就增加功能来说,装饰模式比天生子类更为灵巧
装饰者模式:
装饰者模式动态地将任务附加到工具上。若要扩展功能,装饰者供应了比继续更有弹性的替代方案
装饰模式因此对客户透明的办法动态地给一个工具附加上更多的职责。这也便是说,客户端并不会以为工具在装饰前和装饰后有什么不同。装饰模式可以在不该用创造更多子类的情形下,将工具的功能加以扩展。
装饰模式中紧张角色:
抽象构件(Component)角色:定义一个工具接口,以规范准备吸收附加职责的工具,从而可以给这些工具动态地添加职责。
详细构件(Concrete Component)角色:定义一个将要吸收附加职责的类。
装饰(Decorator)角色:持有一个指向Component工具的指针,并定义一个与Component接口同等的接口。
详细装饰(Concrete Decorator)角色:卖力给构件工具增加附加的职责。
装饰模式的优点:
1、比静态继续更灵巧;
2、避免在层次构造高层的类有太多的特色
装饰模式的缺陷:
1、利用装饰模式会产生比利用继续关系更多的工具。并且这些工具看上去都很想像,从而使得查错变得困难。
装饰模式适用场景:
1、在不影响其他工具的情形下,以动态、透明的办法给单个工具添加职责。
2、处理那些可以撤消的职责,即须要动态的给一个工具添加功能并且这些功能是可以动态的撤消的。
3、当不能彩天生子类的方法进行扩充时。一种情形是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情形可能是由于类定义被隐蔽,或类定义不能用于天生子类。
个人举例:
田老师点餐
装饰模式 一种算法 链表
<?php
namespace haibao\design\web\view\design;
use haibao\design\web\common\design\decorator\Coffee;
use haibao\design\web\common\design\decorator\Milk;
use haibao\design\web\common\design\decorator\Suger;
class Decorator extends \haibao\design\web\view\Base{
protected function preRender(){
header(\"大众Content-type: text/html; charset=utf-8\"大众);
$coffee = new Coffee();
$coffee = new Milk($coffee);
$coffee = new Suger($coffee);
print_R($coffee);
//$coffee = new Milk($coffee);
echo $coffee->cost();
}
}
<?php
/
咖啡类
/
namespace haibao\design\web\common\design\decorator;
class Coffee extends Menu{
public function __construct(){
$this->name = '咖啡';
}
public function cost(){
echo $this->name.\公众<br/>\"大众;
return 2;
}
}
<?php
/
咖啡装饰类
/
namespace haibao\design\web\common\design\decorator;
class CoffeeDecorator extends Menu{
public function __construct(){
}
public function cost(){
return 0.1;
}
}
<?php
/
菜单类
/
namespace haibao\design\web\common\design\decorator;
abstract class Menu{
public $name;
abstract public function cost();
}
<?php
/
牛奶类
/
namespace haibao\design\web\common\design\decorator;
class Milk extends CoffeeDecorator{
public $menu;
public function __construct($menu){
$this->name = '牛奶';
if($menu instanceof Menu){
$this->menu = $menu;
}
}
public function cost(){
echo $this->name.\公众<br/>\"大众;
return $this->menu->cost() + 2;
}
}
<?php
/
牛奶类
/
namespace haibao\design\web\common\design\decorator;
class Suger extends CoffeeDecorator{
public $menu;
public function __construct($menu){
$this->name = '糖块';
if($menu instanceof Menu){
$this->menu = $menu;
}
}
public function cost(){
echo $this->name.\"大众<br/>\公众;
return $this->menu->cost() + 3;
}
}