前言
观察者模式
定义
观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标将情况发送到观察者的。
观察对象的状态发生变化时,通知给观察者。
使用场景
观察者模式适用于根据对象状态进行相应处理的场景。
观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们(Observer)订阅了某个人(Subject)的微博账号,当这个人发布(Action)了新的消息,就会通知(Notify)我们。
基本思路
1.创建被观察的主体(Subject),和观察者(Observer)
2.观察者(Observer)订阅(attach)主体(Subject).
3.主体状态变化(action),通知(notify)所有观察者(Observer)采取措施(update)
实例
秘书等老板回来就同志各个划水的同志停止划水,有看nba的同志,有看股票的同志。
//observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
#include <string>
class Subject;
//抽象观察者
class Observer
{
protected:
std::string name;
Subject *sub;
public:
Observer(std::string name, Subject *sub)
{
this->name = name;
this->sub = sub;
}
virtual void update() = 0;
};
#endif // OBSERVER_H
//subject.h
#ifndef SUBJECT_H
#define SUBJECT_H
#include <list>
#include <string>
class Observer;
//抽象通知者(主体)
class Subject
{
protected:
std::list<Observer*> observers;
public:
std::string action;
virtual void attach(Observer*) = 0;
virtual void detach(Observer*) = 0;
virtual void notify() = 0;
};
#endif // SUBJECT_H
//subject_sercretary.h
#ifndef SUBJECT_SERCRETARY_H
#define SUBJECT_SERCRETARY_H
#include <subject.h>
#include <list>
#include <observer.h>
//秘书
class Secretary :public Subject
{
void attach(Observer *observer)
{
observers.push_back(observer);
}
void detach(Observer *observer)
{
std::list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
if ((*iter) == observer)
{
observers.erase(iter);
}
++iter;
}
}
void notify()
{
std::list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
(*iter)->update();
++iter;
}
}
};
#endif // SUBJECT_SERCRETARY_H
//observer_nba.h
#ifndef OBSERVER_NBA_H
#define OBSERVER_NBA_H
#include <string>
#include <observer.h>
#include <iostream>
#include <subject.h>
class Subject;
using namespace std;
//具体的观察者,看NBA的
class NBAObserver :public Observer
{
public:
NBAObserver(std::string name, Subject *sub) :Observer(name, sub)
{
}
void update();
};
void NBAObserver::update()
{
cout << name << " 收到消息:" << sub->action << endl;
if (sub->action == "梁所长来了!")
{
cout << "我马上关闭NBA,装做很认真工作的样子!" << endl;
}
}
#endif // OBSERVER_NBA_H
//observer_stock.h
#ifndef OBSERVER_STOCK_H
#define OBSERVER_STOCK_H
#include <string>
#include <observer.h>
#include <subject.h>
#include <iostream>
//具体的观察者,看股票的
class StockObserver :public Observer
{
public:
StockObserver(std::string name, Subject *sub) :Observer(name, sub)
{
}
void update();
};
void StockObserver::update()
{
std::cout << name << " 收到消息:" << sub->action << std::endl;
if (sub->action == "梁所长来了!")
{
std::cout << "我马上关闭股票,装做很认真工作的样子!" << std::endl;
}
}
#endif // OBSERVER_STOCK_H
//main.cpp
#include <iostream>
#include <string>
#include <list>
#include <observer_nba.h>
#include <observer_stock.h>
#include <subject.h>
#include <subject_sercretary.h>
using namespace std;
int main()
{
Subject *dwq = new Secretary(); //创建观察者<br> //被观察的对象
Observer *xs = new NBAObserver("xiaoshuai", dwq);
Observer *zy = new NBAObserver("zouyue", dwq);
Observer *lm = new StockObserver("limin", dwq);
//加入观察队列
dwq->attach(xs);
dwq->attach(zy);
dwq->attach(lm);
//事件
dwq->action = "去吃饭了!";
dwq->notify();
cout << endl;
dwq->action = "梁所长来了!";
dwq->notify();
return 0;
}
输出:
xiaoshuai 收到消息:去吃饭了!
zouyue 收到消息:去吃饭了!
limin 收到消息:去吃饭了!
xiaoshuai 收到消息:梁所长来了!
我马上关闭NBA,装做很认真工作的样子!
zouyue 收到消息:梁所长来了!
我马上关闭NBA,装做很认真工作的样子!
limin 收到消息:梁所长来了!
我马上关闭股票,装做很认真工作的样子!