观察者模式

什么是观察者模式

观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

为什么要使用

观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

类型

行为型模式

参与者

  1. SplSubject 被观察者
    • attach
    • detach
    • notify
  2. SplObserver 观察者
    • update
  3. SplObjectStorage 观察者存储类
    • attach
    • detach

例子

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
<?php
/**
* 观察者模式
*/

class Service implements SplSubject {

/**
* @var SplObjectStorage
*/
private $observers;

public $auth;

public $state;

public function __construct()
{
$this->observers = new SplObjectStorage();
}

public function run()
{
$this->auth = 1;
$this->state = 1;
$this->notify();
}

public function upAuth()
{
$this->auth = 10;
$this->notify();
}

public function stop()
{
$this->state = 0;
$this->notify();
}

/**
* 去掉一个观察者
* @param SplObserver $observer
* @return bool
*/
public function detach(SplObserver $observer)
{
$this->observers->detach($observer);
return true;
}

/**
* 增加一个观察者
* @param SplObserver $observer
* @return bool
*/
public function attach(SplObserver $observer)
{
$this->observers->attach($observer);
return true;
}

public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}

class authObserver implements SplObserver {

public function update(SplSubject $subject)
{
if ($subject->state == 1) {
if ($subject->auth < 10) {
echo 'auth 正确'.PHP_EOL;
} else {
echo 'auth 错误'.PHP_EOL;
}
}
}
}

class StateObserver implements SplObserver {

public function update(SplSubject $subject)
{
if ($subject->state != 1) {
echo 'service 停止'.PHP_EOL;
} else {
echo 'service 正常'.PHP_EOL;
}
}
}

class Client {
public function run()
{
$service = new Service();
$authObserver = new authObserver();
$stateObserver = new StateObserver();
$service->attach($authObserver);
$service->attach($stateObserver);
$service->run();
$service->upAuth();
$service->stop();
}
}

$client = new Client();
$client->run();