浅析观察者(Observer)模式
基础定义
多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。文章来源:https://uudwc.com/A/bEP3R
基本结构
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
模式示例
例子
三个不同的观察者对不同的消息msgid有不同的回调处理,通过在主题类注册,便可以在第一时间收到发布后的消息。文章来源地址https://uudwc.com/A/bEP3R
具体实现
//观察者抽象类
class Observer
{
public:
//回调函数
virtual void handle(int msgid)= 0;
};
//观察者1号
class Observer1 :public Observer
{
public:
void handle(int msgid) {
switch (msgid)
{
case 1:
cout << "Observer1 looked 1 msg" << endl;
break;
case 2:
cout << "Observer1 looked 2 msg" << endl;
break;
case 3:
cout << "Observer1 looked 3 msg" << endl;
break;
default:
break;
}
}
};
//观察者2号
class Observer2 :public Observer
{
public:
void handle(int msgid) {
switch (msgid)
{
case 2:
cout << "Observer2 looked 2 msg" << endl;
break;
default:
break;
}
}
};
//观察者3号
class Observer3 :public Observer
{
public:
void handle(int msgid) {
switch (msgid)
{
case 1:
cout << "Observer3 looked 1 msg" << endl;
break;
case 3:
cout << "Observer3 looked 3 msg" << endl;
break;
default:
break;
}
}
};
//主题
class Subject
{
public:
//增加订阅者
void addObserver(Observer* obser ,int msgid) {
//注意重载运算符[]的含义
_subMap[msgid].push_back(obser);
}
//发布
void dispatch(int msgid) {
auto it = _subMap.find(msgid);
for ( auto pObserver : it->second) {
pObserver->handle(msgid);
}
}
private:
//记录订阅者订阅的信息种类
unordered_map<int, list<Observer*>>_subMap;
};
int main()
{
Subject sub;
Observer* p1 = new Observer1();
Observer* p2 = new Observer2();
Observer* p3 = new Observer3();
sub.addObserver(p1, 1);
sub.addObserver(p1, 2);
sub.addObserver(p1, 3);
sub.addObserver(p2, 2);
sub.addObserver(p3, 1);
sub.addObserver(p3, 3);
while (1)
{
int msgid = 0;
cout << "输入消息序号:";
cin >> msgid;
sub.dispatch(msgid);
}
return 0;
}