观察者模式简介:
观察者模式允许我们定义一种订阅机制。可在时间发生时通知所有的观察者对象、使他们能够自动更新。观察者模式还可以叫“发布——订阅”模式
例子:观察者模式的流程可以结合公众号的消息推送进行理解:新闻公众号主要负责推送一些实时新闻,如果你一直订阅关注该公众号,那么该公众号就会一直给你推送消息。
“公众号”就是主题,“你”就是观察者,观察者模式=主题+观察者。
观察者模式代码:
头文件(发布):
#include <string>
#include <iostream>
#include <list>
using namespace std;
class observe;
//基类
class Newagency
{
public:
//添加订阅者
void touch(observe*ob);
//删除订阅者
void del(observe*ob);
//消息推送
virtual void notify(string mergency)=0;
~Newagency() {};
protected:
//这里使用list链表,原因是这里更多的是增添
//和删除订阅者,链表的效率更高
list<observe*> _list;
};
//八卦
class gooip:public Newagency
{
public:
//消息推送
void notify(string mergency) override;
};
//新闻
class Newmsg :public Newagency
{
public:
//消息推送
void notify(string mergency) override;
};
源文件(发布):
#include "Newagency.h"
#define _CRT_SECURE_NO_WARNINGS 1
#include "Newagency.h"
#include "observe.h"
void Newagency::touch(observe* ob)
{
_list.push_back(ob);
}
void Newagency::del(observe* ob)
{
_list.remove(ob);
}
void gooip::notify(string mergency)
{
cout << "八卦新闻的订阅者有<" << _list.size() << ">人" << endl;
for (auto& it : _list)
{
it->update(mergency);
}
}
void Newmsg::notify(string mergency)
{
cout << "新闻的订阅者有<" << _list.size() << ">人" << endl;
for (auto& it : _list)
{
it->update(mergency);
}
}
订阅(头文件)
#include <string>
#include <iostream>
#include "Newagency.h"
using namespace std;
//观察者
class observe
{
public:
//订阅
observe(Newagency* news, string name)
:_news(news)
,_name(name)
{
_news->touch(this);
}
//取消订阅
void unobserve()
{
_news->del(this);
}
//新闻更新
virtual void update(string msg)=0;
virtual ~observe(){}
protected:
Newagency* _news;
string _name;
};
//观察者子类
class cdl :public observe
{
public:
using observe::observe;
//新闻更新
void update(string msg)override
{
cout << "cdl收到的消息: " << msg << endl;
cout << endl;
}
};
class wr :public observe
{
public:
using observe::observe;
//新闻更新
void update(string msg)override
{
cout << "wr收到的消息: " << msg << endl;
cout << endl;
}
};
订阅(源文件):
#include <iostream>
#include "Newagency.h"
#include "observe.h"
using namespace std;
int main()
{
//发布者
Newagency* redbook = new gooip;
Newagency* tengxun = new Newmsg;
//订阅者
observe* Cdl = new cdl(redbook,"cdl");
observe* Wr = new wr(tengxun, "Wr");
redbook->notify("石昊疑似出轨月蝉仙子,火灵儿放言要求其净身出户");
tengxun->notify("韩国乒乓球选手在赛场吃播走红");
delete redbook;
delete tengxun;
delete Cdl;
delete Wr;
return 0;
}