1 模式动机
建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
观察者模式的核心思想是 1对多
2 模式定义
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式是一种对象行为型模式。
3 模式结构
- Subject: 目标
- ConcreteSubject: 具体目标
- Observer: 观察者
- ConcreteObserver: 具体观察者
4 例子
以一个打工人A为例,A下班的时候会告诉孩子和妈妈,A开车要往回走了
- 孩子妈收到消息后开始做饭
- 孩子收到消息后,就赶紧收起手机,怕挨揍
4.1 未重构前
#include <iostream>
class Son{
public:
void DoSomething(){
std::cout<<"爸爸回来了,赶紧去写作业"<<std::endl;
}
};
class Wife{
public:
void DoSomething(){
std::cout<<"老公回来了,去做饭"<<std::endl;
}
};
class Me{
public:
void Gohome(){
wife.DoSomething();
son.DoSomething();
}
private:
Wife wife;
Son son;
};
int main(){
Me me;
me.Gohome();
return 0;
}
这样写的不足如下:
如果关心我的人变多了,比如我又加了我老妈、老爸 ,这时候我们不得不去修改Me的类。假如关心我的人有1000人,那这时候我们该怎么办
class Me{
public:
void Gohome(){
wife.DoSomething();
son.DoSomething();
mom.DoSomething();
ba.DoSomething();
}
private:
Wife wife;
Son son;
Mother mom;
Father ba;
};
4.2 重构后
观察者接口
class ObserverInterface{
public:
virtual void dosomething()=0;
virtual ~ObserverInterface(){}
};
被观察者(目标)接口
class SubjectInterface{
public:
virtual void Add(ObserverInterface* obr)=0;
virtual void Remove(ObserverInterface* obr)=0;
virtual void Notify()=0;
virtual ~SubjectInterface(){}
};
我自己(ConcreteSubject):
class Me:public SubjectInterface{
public:
void Add(ObserverInterface* obr) override{
observers.push_back(obr);
}
void Remove(ObserverInterface* obr) override{
auto pos=std::find(observers.begin(),observers.end(),obr);
if(pos!=observers.end()){
observers.erase(pos);
}
}
void Notify() override{
for(const auto& obs:observers){
obs->dosomething();
}
}
private:
std::vector<ObserverInterface*> observers;
};
孩子妈(ConcreteObserver):
class Wife:public ObserverInterface{
public:
void dosomething() override{
std::cout<<"老公快回来了,开始做饭"<<std::endl;
}
};
孩子(ConcreteObserver):
class Son:public ObserverInterface{
public:
void dosomething() override {
std::cout<<"爸爸快回来了,不能玩游戏了"<<std::endl;
}
};
main函数
int main(){
Me me;
ObserverInterface* wife=new Wife;
ObserverInterface* son=new Son;
me.Add(wife);
me.Add(son);
//下班了 发消息
me.Notify();
delete wife;
delete son;
}
这样的好处是:
- 再增加新的观察者,我们就不用修改Me的类了,只需要添加到vector中就可以
不足是:
- 需要自己做内存管理去 delete,可以改用为智能指针。
参考链接:https://design-patterns.readthedocs.io/zh-cn/latest/behavioral_patterns/observer.html
https://zhuanlan.zhihu.com/p/119308881