观察者模式
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