Decorator 装饰器模式允许我们根据运行时不同的情景动态地为某个对象调用前后添加不同的行为动作

以奇迹暖暖这种换装游戏为例,我们需要实现动态的换套装,或者混搭

我们先创建好装饰器接口:

Decorator.php
1
2
3
4
5
interface Decorator
{
public function beforeDress();
public function afterDress();
}

实现一个警察装扮:

PoliceDecorator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class PoliceDecorator implements Decorator
{
public function beforeDress()
{
echo "穿上警服" . PHP_EOL;
}

public function afterDress()
{
echo "穿上防弹衣" . PHP_EOL;
echo "带好配枪" . PHP_EOL;
echo "别上警徽" . PHP_EOL;
echo "戴上警帽" . PHP_EOL;
echo "穿戴完毕" . PHP_EOL;
}
}

再实现一个护士装扮:

NurseDecorator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class NurseDecorator implements Decorator
{
public function beforeDress()
{
echo "无" . PHP_EOL;
}

public function afterDress()
{
echo "穿上粉色大褂" . PHP_EOL;
echo "戴上护士帽" . PHP_EOL;
echo "戴上口罩" . PHP_EOL;
echo "穿戴完毕" . PHP_EOL;
}
}

最后实现一个穿衣服的人:

Person.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Person
{
protected $decorators = []];

public function addDecorator(Decorator $decorator)
{
$this->decorators[] = $decorator;
}

public function beforeDress()
{
foreach ($this->decorators as $decorator) {
$decorator->beforeDress();
}
}

public function afterDress()
{
$decorators = array_reverse($this->decorators);
foreach ($decorators as $decorator) {
$decorator->afterDress();
}
}

public function dress()
{
$this->beforeDress();
echo "穿上纯白短袖" . PHP_EOL;
$this->afterDress();
}
}

现在我们可以创建一个混搭女生青年了:

1
2
3
4
$girl = new Person;
$girl->addDecorator(new PoliceDecorator);
$girl->addDecorator(new NurseDecorator);
$girl->dress();