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
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

/**
* 观察者接口
*/
interface ObserverInterface
{
/**
* 行为
* @return void
*/
public function doSomething(ObservableInterface $observable);
}

/**
* 观察者实体类示例1
*/
class ObserverExampleOne implements ObserverInterface
{
/**
* 行为
* @return mixed
*/
public function doSomething(ObservableInterface $observable)
{
echo $observable->_name . "通知了观察者1 \n";
}
}

/**
* 观察者实体类示例2
*/
class ObserverExampleTwo implements ObserverInterface
{
/**
* 行为
* @return mixed
*/
public function doSomething(ObservableInterface $observable)
{
echo $observable->_name . "通知了观察者2 \n";
}
}

/**
* 被观察者接口
*
* 需要实现附加观察者,删除观察者,通知观察者方法
*/
interface ObservableInterface
{
/**
* 附加观察者
* @return void
*/
public function attach(ObserverInterface $observer);

/**
* 解除观察者
* @return void
*/
public function detach(ObserverInterface $observer);

/**
* 通知观察者
* @return void
*/
public function notify();
}

/**
* 被观察者实体类
*
* 实现附加观察者,删除观察者,通知观察者方法
*/
class Observable implements ObservableInterface
{
/**
* 观察者们
* @var array
*/
private $_observers = [];

/**
* 被观察者名称
* @var string
*/
private $_name = '【被观察者:皮皮虾】';

/**
* 魔术方法 __get
* @param string $name 属性名称
* @return mixed
*/
public function __get($name='')
{
return $this->$name;
}

/**
* 附加观察者
* @return void
*/
public function attach(ObserverInterface $observer)
{
if (!in_array($observer, $this->_observers, true)) {
$this->_observers[] = $observer;
}
}

/**
* 解除观察者
* @return void
*/
public function detach(ObserverInterface $observer)
{
foreach ($this->_observers as $k => $v) {
if ($v === $observer) {
unset($this->_observers[$k]);
}
}
}

/**
* 通知观察者
* @return void
*/
public function notify()
{
foreach ($this->_observers as $v) {
$v->doSomething($this);
}
}
}

// 注册一个被观察者对象
$observable = new Observable();
// 注册观察者们
$observerExampleOne = new ObserverExampleOne();
$observerExampleTwo = new ObserverExampleTwo();

// 附加观察者
$observable->attach($observerExampleOne);
$observable->attach($observerExampleTwo);

// 被观察者通知观察者们
$observable->notify();