设计模式探秘-19-观察者模式

观察者模式的学习与实践,观察者模式是软件开发过程中必须掌握和使用的模式之一。

观察者模式

观察者模式(发布订阅模式):定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

类图

  1. Subject 被观察者 定义被观察者必须实现的职责,必须能能够动态地增加、删除观察者。一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
  2. Observer 观察者 观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
  3. ConcreteSubject 具体的被观察者 定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
  4. ConcreteObserver 具体的观察者 每个观察者在接收到信息后的处理反应是不同的,各个观察者有自己的处理流程。

优点

  1. 观察者和被观察者之间是抽象耦合,增加观察者和被观察者非常容易扩展。
  2. 建立一套触发机制。

缺点

开发效率和运行效率问题。

使用场景

  1. 关联行为场景。关联行为是可拆分的,而不是“组合”关系。
  2. 事件多级触发场景。
  3. 跨系统的消息交换场景。

注意事项

  1. 广播链的问题。建议一个观察者模式中最多出现一个对象既是观察者也是被观察者。
  2. 异步处理问题。

扩展

实践

简单实现

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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <iostream>
#include <list>
#include <string>

using namespace std;

typedef string State;

class Observer;

class Subject
{
public:
virtual ~Subject()
{
}

virtual void Attach(Observer *obv)
{
m_lObvs.push_front(obv);
}
virtual void Detach(Observer *obv)
{
if(obv != NULL)
{
m_lObvs.remove(obv);
}
}
virtual void Notify();
virtual void SetState(const State &st) = 0;
virtual State GetState() = 0;
protected:
Subject()
{
}
private:
list<Observer *> m_lObvs;
};


class ConcreteSubject : public Subject
{
public:
ConcreteSubject()
{
}
~ConcreteSubject()
{
}
State GetState()
{
return m_sSt;
}
void SetState(const State& st)
{
m_sSt = st;
Notify();
}
private:
State m_sSt;
};

class Observer
{
public:
virtual ~Observer()
{
}
virtual void Update(Subject *sub) = 0;
virtual void PrintInfo() = 0;
protected:
Observer()
{
}
State m_sSt;
};

class ConcreteObserverA : public Observer
{
public:
virtual Subject *GetSubject()
{
return m_pSub;
}
ConcreteObserverA(Subject *sub)
{
m_pSub = sub;
m_pSub->Attach(this);
}
virtual ~ConcreteObserverA()
{
m_pSub->Detach(this);
}
void Update(Subject *sub)
{
m_sSt = m_pSub->GetState();
PrintInfo();
}
void PrintInfo()
{
cout<<"A "<<m_pSub->GetState()<<endl;
}
private:
Subject *m_pSub;
};

class ConcreteObserverB : public Observer
{
public:
virtual Subject *GetSubject()
{
return m_pSub;
}
ConcreteObserverB(Subject *sub)
{
m_pSub = sub;
m_pSub->Attach(this);
}
virtual ~ConcreteObserverB()
{
m_pSub->Detach(this);
}
void Update(Subject *sub)
{
m_sSt = m_pSub->GetState();
PrintInfo();
}
void PrintInfo()
{
cout<<"B "<<m_pSub->GetState()<<endl;
}
private:
Subject *m_pSub;
};

void Subject::Notify()
{
for(auto pObv : m_lObvs)
{
if(pObv != NULL)
{
pObv->Update(this);
}
}
}

int main()
{
ConcreteSubject *sub = new ConcreteSubject();
Observer *o1 = new ConcreteObserverA(sub);
sub->SetState("state1");
Observer *o2 = new ConcreteObserverB(sub);
sub->SetState("state2");
sub->SetState("state3");

delete o1;
delete o2;
delete sub;

return 0;
}

参考资料

  1. 设计模式之禅
  2. GoF+23种设计模式解析