[toc]
## 举个例子
**程序员为了找女朋友, 开始注意着装和形象了...**
* 头上带一副方形黑框眼镜。
* 上面是一件紫红色针织毛衣,内套一件白色衬衫;
* 下面是一条卡其色休闲裤配一双深色休闲皮鞋,加一条银色针扣头的黑色腰带;
* 整体行装虽不潮流,却透露出一种工作人士的成熟、稳健和大气!
* 人还是那个人, 不同的着装, 体现不同的性格和形象.
## 代码示例
```php
<?php
// 人
class Person {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function wear() {
echo "我的着装是:" . PHP_EOL;
}
}
// 工程师
class Engineer extends Person {
private $skill;
public function __construct($name, $skill) {
parent::__construct($name);
$this->skill = $skill;
}
public function getSkill() {
return $this->skill;
}
public function wear() {
echo "我是" . $this->getSkill() . "工程师" . $this->getName() . PHP_EOL;
parent::wear();
}
}
// 教师
class Teacher extends Person {
private $title;
public function __construct($name, $title) {
parent::__construct($name);
$this->title = $title;
}
public function getTitle() {
return $this->title;
}
public function wear() {
echo "我是" . $this->getName() . $this->getTitle() . PHP_EOL;
parent::wear();
}
}
// 服装装饰器
class ClothingDecorator extends Person {
protected $decorated;
public function __construct($person) {
$this->decorated = $person;
}
public function wear() {
$this->decorated->wear();
}
}
// 休闲裤
class CasualPantDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一条卡其色休闲裤" . PHP_EOL;
}
}
// 腰带
class BeltDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一条银色针扣头的黑色腰带" . PHP_EOL;
}
}
// 皮鞋
class LeatherShoesDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一双深色休闲皮鞋" . PHP_EOL;
}
}
// 针织毛衣
class KnittedSweaterDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一件紫红色针织毛衣" . PHP_EOL;
}
}
// 白色衬衫
class WhiteShirtDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一件白色衬衫" . PHP_EOL;
}
}
// 眼镜
class GlassesDecorator extends ClothingDecorator {
public function __construct($person) {
parent::__construct($person);
}
public function wear() {
parent::wear();
echo "一副方形黑框眼镜" . PHP_EOL;
}
}
$tony = new Engineer("Tony", "客户端");
$pant = new CasualPantDecorator($tony);
$belt = new BeltDecorator($pant);
$shoes = new LeatherShoesDecorator($belt);
$shirt = new WhiteShirtDecorator($shoes);
$sweater = new KnittedSweaterDecorator($shirt);
$glasses = new GlassesDecorator($sweater);
$glasses->wear();
echo PHP_EOL;
$decorateTeacher = new GlassesDecorator(new WhiteShirtDecorator(new LeatherShoesDecorator(new Teacher("wells", "教授"))));
$decorateTeacher->wear();
```
```
D:\soft\php72\php.exe D:\project\php_dp\index.php
我是客户端工程师Tony
我的着装是:
一条卡其色休闲裤
一条银色针扣头的黑色腰带
一双深色休闲皮鞋
一件白色衬衫
一件紫红色针织毛衣
一副方形黑框眼镜
我是wells教授
我的着装是:
一双深色休闲皮鞋
一件白色衬衫
一副方形黑框眼镜
Process finished with exit code 0
```
## 什么是装饰模式?
> 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。
![](https://box.kancloud.cn/e57b8047725caa41cd058a7f5e50d9cb_549x413.png)
## 模式特点
1. 可灵活地给一个对象增加职责或拓展功能
如上面的示例中,可任意地穿上自己想穿的衣服。不管穿上什么衣服,你还是那个你,但穿上不同的衣服你就会有不同的外表。
1. 可增加任意多个装饰
你可以只穿一件衣服,也可以只穿一条裤子,也可以衣服和裤子各种搭配的穿,全随你意!
1. 装饰的顺序不同,可能产生不同的效果
内裤穿在里面是正常人, 内裤外穿就变成了超人
## 优缺点
**装饰模式的优点**:
1.使用装饰模式来实现扩展比继承更加灵活,它可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
1. 可以动态地给一个对象附加更多的功能。
1. 可以用不同的装饰器进行多重装饰,装饰的顺序不同,可能产生不同的效果。
1. 装饰类和被装饰类可以独立发展,不会相互耦合;装饰模式相当于是继承的一个替代模式。
**装饰模式的缺点**:
1. 与继承相比,用装饰的方式拓展功能更加容易出错,排错也更困难。对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
## 应用场景
1. 有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
1. 需要动态地增加或撤销功能时。
1. 不能采用生成子类的方法进行扩充时,如类定义不能用于生成子类。