觀察者模式又被稱為發布訂閱模式,它定義了物件之間一對多的依賴,當一個物件狀態發生改變時,它的所有依賴者都會收到通知并自動更新相關內容,即建立一個(Subject類)對多(Observer類)的關系,能夠使得當Subject的物件變化的時候,依賴這個的多個Observe的物件實體也能夠同步進行相應的改變,
優點: 1、觀察者和被觀察者是抽象耦合的, 2、可以建立一套觸發機制,
缺點: 1、如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間,
2、如果在觀察者和觀察目標之間有回圈依賴的話,觀察目標會觸發它們之間進行回圈呼叫,可能導致系統崩潰,
3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎么發生變化的,而僅僅只是知道觀察目標發生了變化,
設計骨架如下:

各個角色解釋如下:
抽象Subject角色:抽象主題角色提供維護一個觀察者物件集合的操作方法,對集合的增加、洗掉等,
具體ConcreteSubject角色:將有關狀態存入具體的觀察者物件;在具體主題的內部狀態改變時,給所有登記過的觀察者發通知,具體主題角色負責實作抽象基類中的方法,
抽象Observer角色:為具體觀察者提供一個更新介面,
具體ConcreteObserver角色:存盤自身的狀態,實作抽象觀察者提供的更新改變的介面,
舉一個老板與職員的例子,在某IT公司的上午,有幾個員工在上班偷偷劃水,但怕被老板發現,他們讓離老板辦公室最近的小A負責望風,當老板來時,通知小B,小C,小D他們做出改變,要編程來描述這個程序,這里就可以用觀察者模式來實作了,把小A當做Subject,其他要通知的員工則是Observer,代碼如下:
#include <iostream>
#include<vector>
using namespace std;
class Observer;
//抽象被觀察者
class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
virtual string GetState()
{
return state_;
}
void SetState(string state)
{
state_= state;
}
protected:
vector<Observer *> ob;
string state_;
};
//具體被觀察者
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver)
{
ob.push_back(pObserver);
}
void Detach(Observer *pObserver)
{
vector<Observer*>::iterator t;
for(t=ob.begin(); t!=ob.end(); t++)
if(*t==pObserver)
ob.erase(t);
}
void Notify();
};
//抽象觀察者
class Observer
{
protected:
Subject *subject;
public:
Observer(Subject *s)
{
subject = s;
subject->Attach(this);
}
virtual void Update() = 0;
};
//核心操作:回圈通知所有觀察者
void ConcreteSubject::Notify()
{
vector<Observer*>::iterator t;
for(t=ob.begin(); t!=ob.end(); t++)
(*t)->Update();
}
//具體觀察者1
class Observer1 : public Observer
{
public:
Observer1(Subject *s): Observer(s)
{
cout<<"小B在看電影"<< endl;
}
virtual void Update()
{
cout << subject->GetState() << ",小B開始好好作業"<< endl;
}
};
//具體觀察者2
class Observer2 : public Observer
{
public:
Observer2(Subject *s): Observer(s)
{
cout <<"小C在玩游戲"<< endl;
}
virtual void Update()
{
cout << subject->GetState() << ",小C開始好好作業"<< endl;
}
};
//具體觀察者2
class Observer3 : public Observer
{
public:
Observer3(Subject *s): Observer(s)
{
cout <<"小D在聊天"<< endl;
}
virtual void Update()
{
cout << subject->GetState() << ",小D開始好好作業"<< endl;
}
};
int main()
{
// 創建被觀察者
Subject *p_subject = new ConcreteSubject();
// 創建觀察者
Observer *p_observer1 = new Observer1(p_subject);
Observer *p_observer2 = new Observer2(p_subject);
Observer *p_observer3 = new Observer3(p_subject);
// 改變狀態
cout<<"老板來了,小A通知"<<endl;
p_subject->SetState("老板來了");
p_subject->Notify();
cout<<"小B不需要通知"<<endl;
// 注銷觀察值小B
p_subject->Detach(p_observer1);
cout<<"老板又來了,小A通知"<<endl;
p_subject->SetState("老板來了");
p_subject->Notify();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/54939.html
標籤:C++
