引言
观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。这种模式通常用于实现事件处理系统、发布-订阅模型等。
观察者模式
- 试想这样一个场景,有一个超市,里面有很多员工,他们需要共同管理这个超市
- 当员工入职的时候,员工就会与超市产生联系,订阅超市信息
- 这个时候,一个员工提出超市售卖商品进行折扣售卖,被超市采纳了。此时超市的相关信息被更改了,这时候超市就要通知所有的员工,不再按照原来价格进行售卖,而是用折扣价进行售卖。
- 过了几天后,又有个员工提出了另一种营销策略,被超市采纳,超市也要通知所有员工新的售卖策略
上述的情景就用到了观察者模式,超市是被观察的对象,员工就是观察者,当被观察的对象信息发生改变,就要告诉所有的观察者信息改变,观察者也能根据信息改变进行自己的处理。
源码实现
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
|
//有一个抽象的观察者,观察某一个行为,并针对这一行为有一个抽象的处理
//具体的观察者继承继承抽象的观察者,同时实现自己的具体的处理
//对于被观察的行为,行为的发起者有一个观察者列表,发起行为时,调用所有观察者的具体处理
#include <iostream>
#include <vector>
using namespace std;
class AbstractObserver {
public:
virtual void DoProcess(int num) = 0; //通知观察者对象,需要进行重写
virtual void ChangeSubject(int data) = 0;
virtual ~AbstractObserver() = default;
};
class AbstractSubject {
public:
virtual ~AbstractSubject() = default;
virtual void ChangeData(int) = 0;
virtual void NotifyObservers() = 0;
void AddObserver(AbstractObserver* observer) {observers.push_back(observer);}
void RemoveObserver(const AbstractObserver* observer) {
for (auto it = observers.begin(); it != observers.end(); ++it) {
if (*it == observer) {
observers.erase(it);
}
}
}
protected:
vector<AbstractObserver*> observers;
};
class Observer1 final : public AbstractObserver {
public:
explicit Observer1(AbstractSubject* subject) : subject_(subject) {
subject_->AddObserver(this);
}
void DoProcess(const int num) override {cout << "Observer1 : " << num << endl;}
void ChangeSubject(const int data) override {subject_->ChangeData(data);}
private:
AbstractSubject* subject_;
};
class Observer2 final : public AbstractObserver {
public:
explicit Observer2(AbstractSubject* subject) : subject_(subject) {
subject_->AddObserver(this);
}
void DoProcess(const int num) override {cout << "Observer2 : " << num << endl;}
void ChangeSubject(const int data) override {subject_->ChangeData(data);}
private:
AbstractSubject* subject_;
};
class Observer3 final : public AbstractObserver {
public:
explicit Observer3(AbstractSubject* subject) : subject_(subject) {
subject_->AddObserver(this);
}
void DoProcess(const int num) override {cout << "Observer3 : " << num << endl;}
void ChangeSubject(const int data) override {subject_->ChangeData(data);}
private:
AbstractSubject* subject_;
};
class Subject final : public AbstractSubject {
public:
explicit Subject(const int data = 0) : data_(data){}
void ChangeData(const int data) override {
data_ = data;
NotifyObservers();
}
void NotifyObservers() override {
for (const auto & observer : observers) {
observer -> DoProcess(data_);
}
}
private:
int data_;
};
int main() {
AbstractSubject* subject = new Subject();
AbstractObserver* observer1 = new Observer1(subject);
AbstractObserver* observer2 = new Observer2(subject);
AbstractObserver* observer3 = new Observer3(subject);
observer1 -> ChangeSubject(2); //观察者1更改目标,所有观察者都应该显示更改后的目标
cout << "-------------------------------" << endl;
observer2 -> ChangeSubject(612); //观察者2更改目标,所有观察者都应该显示更改后的目标
subject -> RemoveObserver(observer1); //删除1号观察者
cout << "-------------------------------" << endl;
observer3 -> ChangeSubject(100); //观察者3更改目标,所有观察者都应该显示更改后的目标
delete subject;
delete observer1;
delete observer2;
delete observer3;
}
|
下面就来说明上面代码中每一个类的作用
使用的时候,用抽象被观察对象类型指针接受一个具体的被观察对象指针,新建具体观察者的时候,传入这个指针(将被观察对象和观察者联系起来)。当一个观察者调用ChangeSubject时,其被观察对象会调用ChangeData函数更改信息,ChangeData函数里面还会调用NotifyObservers函数,在NotifyObservers函数里面,所有观察者会调用DoProcess应对被观察对象的数据变化。