10.观察者模式
1觀察者模式的核心內容是:
A:要有被監視的對象,案例中的是Subject
B:要有觀察者,相當于被監視的對象的粉絲
C:被監視的對象存儲自己的粉絲,也解釋粉絲。其內部的方法方法通知自己的粉絲情況。
2觀察者模式的作用:相當于模擬公司職員監視老板的情況。
3觀察者模式具體描述
觀察者模式:觀察者模式定義了一種一對多的依賴關系,
讓多個觀察者對象同時監聽某一個主題對象。
這個主題對象在狀態上發生變化時,會通知所有觀察者對象,
使他們能夠自動更新自己。
?
想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,
tom負責搜集情報,他發現的新情報不用一個一個通知我們,
直接發布給郵件組,我們作為訂閱者(觀察者)就可以及時收到情報啦。
?
監視,觀察者,都有一個基類,派生,實現不同的效果
監視者的類,管理所有的觀察者,增加或者刪除,發出消息,讓觀察者處理
觀察者的類需要接受消息并處理
4.觀察者模式類圖
5.代碼:
#include<iostream>
#include <string>
#include <list>
using namespace std;
?
//觀察者模式:觀察者模式定義了一種一對多的依賴關系,
//讓多個觀察者對象同時監聽某一個主題對象。
//這個主題對象在狀態上發生變化時,會通知所有觀察者對象,
//使他們能夠自動更新自己。
//
//想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,
//tom負責搜集情報,他發現的新情報不用一個一個通知我們,
//直接發布給郵件組,我們作為訂閱者(觀察者)就可以及時收到情報啦。
?
// 監視,觀察者,都有一個基類,派生,實現不同的效果
//監視者的類,管理所有的觀察者,增加或者刪除,發出消息,讓觀察者處理
//觀察者的類需要接受消息并處理
?
//要監聽的某一個主題對象
class Subject;
?
//觀察者:觀察別人變化(粉絲)
class Observer
{
protected:
??? string name;
??? Subject *sub;
public:
??? //這里是指觀察者的名字,監視與通知的類
??? Observer(string name, Subject *sub)
??? {
??????? this->name = name;//輸入名字
??????? this->sub = sub;? //設置誰來通知我
??? }
??? virtual void update() = 0;//純虛函數
};
?
//繼承,自己實現刷新函數,這里是一個股票觀察者
class StockObserver :public Observer
{
public:
??? StockObserver(string name, Subject *sub) :Observer(name, sub)
??? {
??? }
??? void update();
};
?
//觀察者,相當于粉絲
class NBAObserver :public Observer
{
public:
??? NBAObserver(string name, Subject *sub) :Observer(name, sub)
??? {
??? }
??? void update();
};
?
//被監視的對象的抽象類
class Subject
{
protected:
??? //存儲觀察者的指針,鏈表
??? list<Observer*> observers;
public:
??? string action;
??? virtual void attach(Observer*) = 0;//添加觀察者
??? virtual void detach(Observer*) = 0;//刪除觀察者
??? virtual void notify() = 0;//實現監聽的基類
};
?
//部長類,它是要被監視的對象
class Secretary :public Subject
{
??? //載入通知的列表
??? void attach(Observer *observer)
??? {
??????? observers.push_back(observer);
??? }
??? //刪除
??? void detach(Observer *observer)
??? {
??????? list<Observer *>::iterator iter = observers.begin();
??????? while (iter != observers.end())
??????? {
??????????? if ((*iter) == observer)
??????????? {
??????????????? observers.erase(iter);
??????? ??? }
??????????? ++iter;
??????? }
??? }
??? //通知函數
??? void notify()
??? {
??????? list<Observer *>::iterator iter = observers.begin();
??????? while (iter != observers.end())
??????? {
??????????? (*iter)->update();
??????????? ++iter;
??????? }
??? }
};
?
void StockObserver::update()
{
??? cout << name << " 收到消息:" << sub->action << endl;
??? if (sub->action == "梁所長來了!")
??? {
??????? cout << "我馬上關閉股票,裝做很認真工作的樣子!" << endl;
??? }
??? if (sub->action == "去喝酒!")
??? {
??????? cout << "我馬上走" << endl;
??? }
}
?
void NBAObserver::update()
{
??? cout << name << " 收到消息:" << sub->action << endl;
??? if (sub->action == "梁所長來了!")
??? {
??????? cout << "我馬上關閉NBA,裝做很認真工作的樣子!" << endl;
??? }
?
??? if (sub->action == "去喝酒!")
??? {
??????? cout << "我馬上拍" << endl;
??? }
}
?
int main()
{
??? Subject *dwq = new Secretary();//消息監視,監視
?
??? //下面的三者都相當于是Secretary的粉絲
??? 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();
??? dwq->action = "去喝酒!";
??? dwq->notify();
??? cout << endl;
??? dwq->action = "梁所長來了!";
??? dwq->notify();
??? cin.get();
??? return 0;
}
運行結果如下:
總結