前言
观察者模式
定义
观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标将情况发送到观察者的。
观察对象的状态发生变化时,通知给观察者。
使用场景
观察者模式适用于根据对象状态进行相应处理的场景。
观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们(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 收到消息:梁所长来了! 我马上关闭股票,装做很认真工作的样子!