Observer

观察者

定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
让主题和观察者之间松耦合。

典型情境

订报纸。订阅者可以及时得到消息。可以申请添加为订阅者。也可以取消订阅。
出版者 + 订阅者 = 观察者模式

适用性

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这两者封装在独立的对象中以使他们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。

结构

Observer Class
Observer Class
Observer Sequence

Subject - 目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者的接口。
Observer - 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
ConcreteSubject - 将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。
ConcreteObserver - 维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。

协作:
当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。
在得到一个具体目标的改变通知后,ConcreteObserver对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。

示例

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
#include <iostream>
#include <list>
//---------------------------------------------------
class Subject;
class Observer
{
public:
virtual ~Observer() {}
virtual void update(Subject* the_changed_subject) = 0;
protected:
Observer(){}
};
//---------------------------------------------------
class Subject
{
public:
virtual ~Subject(){}
virtual void register_observer(Observer* obs)
{

if (!obs) return;
m_observers.push_back(obs);
}
virtual void unregister_observer(Observer* obs)
{

if (!obs) return;
m_observers.remove(obs);
}
virtual void notify_observer()
{

for (std::list<Observer*>::iterator it = m_observers.begin(); it != m_observers.end(); ++it)
{
if (!(*it)) continue;
(*it)->update(this);
}
}
protected:
Subject(){}
std::list<Observer*> m_observers;
};
//---------------------------------------------------
class ConcreteSubject : public Subject
{
public:
ConcreteSubject():m_subject_state(0){}
int get_state()
{

return m_subject_state;
}
int set_state(int st)
{

m_subject_state = st;
}
void process()
{

m_subject_state += 10;
std::cout << "ConcreteSubject current state: " << m_subject_state << std::endl;
}
protected:
int m_subject_state;
};
//---------------------------------------------------
class ConcreteObserver : public Observer
{
public:
virtual void update(Subject* the_changed_subject)
{

ConcreteSubject* subject = dynamic_cast<ConcreteSubject*>(the_changed_subject);
m_observer_state = subject->get_state();
std::cout << "ConcreteObserver get state: " << m_observer_state << std::endl;
}
protected:
int m_observer_state;
};
//---------------------------------------------------
int main()
{

ConcreteSubject cs;
ConcreteObserver co;
cs.register_observer(&co);
cs.process();
cs.notify_observer();
cs.process();
cs.process();
cs.notify_observer();
cs.unregister_observer(&co);
cs.process();
cs.notify_observer();
system("Pause");
}

相关模式

  • Mediator: 通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介者。
  • Singleton: ChangeManager可使用Singleton模式来保证它是唯一的并且是可全局访问的。

[1] 设计模式:可复用面向对象软件的基础
[2] Head First设计模式