概念
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
UML图
角色
抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这些对象动态地添加职责。
具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。可以给这个类的对象添加一些职责
抽象装饰器(Decorator):维持一个指向构件Component对象的实例,并定义一个与抽象组件角色Component接口一致的接口
具体装饰器角色(ConcreteDecorator):向组件添加职责。
适用场景
需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
代码
代码:
<?php
header('Content-type:text/html;charset=utf-8');
/**
* 装饰器模式
*/
/**
* Interface IComponent 组件对象接口
*/
interface IComponent
{
public function display();
}
/**
* Class Person 待装饰对象
*/
class Person implements IComponent
{
private $_name;
/**
* Person constructor. 构造方法
*
* @param $name 对象人物名称
*/
public function __construct($name)
{
$this->_name = $name;
}
/**
* 实现接口方法
*/
public function display()
{
echo "装扮者:{$this->_name}<br/>";
}
}
/**
* Class Clothes 所有装饰器父类-服装类
*/
class Clothes implements IComponent
{
protected $component;
/**
* 接收装饰对象
*
* @param IComponent $component
*/
public function decorate(IComponent $component)
{
$this->component = $component;
}
/**
* 输出
*/
public function display()
{
if(!empty($this->component))
{
$this->component->display();
}
}
}
/**
* 下面为具体装饰器类
*/
/**
* Class Sneaker 运动鞋
*/
class Sneaker extends Clothes
{
public function display()
{
echo "运动鞋 ";
parent::display();
}
}
/**
* Class Tshirt T恤
*/
class Tshirt extends Clothes
{
public function display()
{
echo "T恤 ";
parent::display();
}
}
/**
* Class Coat 外套
*/
class Coat extends Clothes
{
public function display()
{
echo "外套 ";
parent::display();
}
}
/**
* Class Trousers 裤子
*/
class Trousers extends Clothes
{
public function display()
{
echo "裤子 ";
parent::display();
}
}
/**
* 客户端测试代码
*/
class Client
{
public static function test()
{
$zhangsan = new Person('张三');
$lisi = new Person('李四');
$sneaker = new Sneaker();
$coat = new Coat();
$sneaker->decorate($zhangsan);
$coat->decorate($sneaker);
$coat->display();
echo "<hr/>";
$trousers = new Trousers();
$tshirt = new Tshirt();
$trousers->decorate($lisi);
$tshirt->decorate($trousers);
$tshirt->display();
}
}
Client::test();
运行结果:
外套 运动鞋 装扮者:张三
T恤 裤子 装扮者:李四
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。