装饰器模式主要用于动态添加修改类的功能。

一般情况下,一个类提供了某些功能,如果要扩展或修改该类,我们可以扩展一个子类出来。但是装饰器模式可以使我们更为灵活的实现。

那么,装饰器模式相对继承灵活在哪儿呢?

举个🌰,我们有一个发送短信的类,现在要在发送短信前增加一些校验,发送短信后我们要记录 log:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
interface SendSms
{
public function Send();
}


interface Decorator
{

public function beforeSend();

public function afterSend();

}


class SmsDecorator implements Decorator{

public function beforeSend()
{
echo 'check', PHP_EOL;
}

public function afterSend()
{
echo 'log', PHP_EOL;
}
}

class AuthSms implements SendSms
{

protected $decorators = [];

public function addDecorator(Decorator $decorator)
{
array_push($this->decorators, $decorator);
}

protected function beforeSend()
{
/**
* @var Decorator $decorator
*/
foreach ($this->decorators as $decorator) {
$decorator->beforeSend();
}
}

protected function afterSend()
{

$decorators = array_reverse($this->decorators);
/**
* @var Decorator $decorator
*/
foreach ($decorators as $decorator) {
$decorator->afterSend();
}
}

public function Send()
{
$this->beforeSend();
echo 'auth sms is send', PHP_EOL;
$this->afterSend();
}

}


$sms = new AuthSms();
$sms->addDecorator(new SmsDecorator());
$sms->send();