观察者模式

观察者模式

3e2d09a0d658725d19171a878dacd5cd.png

适用于“一对多”的依赖关系。当一个对象的状态发生变化时,它能够自动通知所有依赖于它的对象,而不需要主动调用它们。

其中,观察者(Observer)随时可以离开(将不会收到通知),随时可以加入(收到通知后会更新)。

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
#include <iostream>
#include <list>
#include <utility>
#include <memory>

using namespace std;

class Observer;
class Subject { // 主题基类
public:
// 添加观察者
void add(Observer *observer) {
observer_list.push_back(observer);
}

// 删除观察者
void del(Observer *observer) {
observer_list.remove(observer);
}

// 通知观察者
virtual void notify(std::string msg) = 0;

virtual ~Subject() {
cout << " ~Subject() " << endl;
};
protected:
// 管理观察者
list<Observer *> observer_list;
};

class Observer { // 观察者基类
public:
virtual void update(std::string msg) = 0;

explicit Observer(std::string name) : name_(std::move(name)) {}

virtual ~Observer() {
cout << " ~Observer() " << endl;
};

void subscribe(shared_ptr<Subject> subject) { // 订阅
subject_ = subject;
subject_->add(this);
}

void unsubscribe() { // 取消订阅
subject_->del(this);
}

public:
std::string name_;
shared_ptr<Subject> subject_; // 只能订阅一个主题
};

class New : public Subject { // 具体主题(新闻)
public:
void notify(std::string msg) override {
cout << "subscribe New people : " << observer_list.size() << endl;
for (const auto &observer : observer_list) {
observer->update(msg);
}
}

~New() override {
cout << " ~New() " << endl;
}
};

class TV : public Subject { // 具体主题(电视台)
public:
void notify(std::string msg) override {
cout << "subscribe TV people : " << observer_list.size() << endl;
for (const auto &observer : observer_list) {
observer->update(msg);
}
}

~TV() override {
cout << " ~TV() " << endl;
}
};

class Teacher : public Observer { // 具体观察者(老师)
public:
void update(std::string msg) override {
cout << "Teacher " << name_ << " get message : " << msg << endl;
}

explicit Teacher(std::string name) : Observer(std::move(name)) {}

~Teacher() override {
cout << " ~Teacher() " << endl;
}
};

class Student : public Observer { // 具体观察者(学生)
public:
void update(std::string msg) override {
cout << "Student " << name_ << " get message : " << msg << endl;
}

explicit Student(std::string name) : Observer(std::move(name)) {}

~Student() override {
cout << " ~Student() " << endl;
}
};

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main() {

// 创建一个主题
shared_ptr<Subject> new_sub = make_shared<New>();

// 创建多个观察者
std::string name_xy = "xy";
shared_ptr<Observer> s_xy = make_shared<Student>(name_xy);
s_xy->subscribe(new_sub);

std::string name_li = "li";
shared_ptr<Observer> t_li = make_shared<Teacher>(name_li);
t_li->subscribe(new_sub);

new_sub->notify("New news available!");

t_li->unsubscribe();

new_sub->notify("New news Test");

return 0;
}

和发布-订阅模式的区别

4fd5710dbf0981453cf21c45f84931b8.png

前面我们看到观察者模式,可以有多个主题,一个主题有多个观察者,而一个观察者只能订阅一个主题。

但是发布订阅就不同,由一个发布者管理多个主题,多个主题有多个订阅者,一个订阅者可以订阅多个主题,这就是两者的区别。

发布订阅中,订阅者通过发布者订阅主题,主题有消息通过发布者通知订阅者。