舉例: 對同一組數據進行統計分析時候, 我們希望能夠提供多種形式的表示 (例如以表格進行統計顯示、柱狀圖統計顯示、百分比統計顯示等)。這些表示都依賴於同一組數據, 我們當然需要當數據改變的時候, 所有的統計的顯示都能夠同時改變。 Observer 模式就是解決了這一個問題。
總結:解決一對多的問題,同時保證觀察者與被觀察者之間爲鬆耦合。
下面代碼展示了Observer模式的整個框架和流程。
#include <iostream>
#include <list>
using namespace std;
class Observer;
//抽象被觀察者
class Subject {
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
virtual int GetState() { return state_; }
void SetState(int state) { state_ = state; }
protected:
std::list<Observer *> observer_list_;
int state_;
};
//抽象觀察者
class Observer {
public:
Observer(Subject *sub):p_subject_(sub){}
virtual void Update() = 0;
protected:
Subject* p_subject_;
};
//具體觀察者1
class Observer1 : public Observer {
public:
Observer1(Subject *p_subject) : Observer(p_subject) {}
void Update() override {
cout << "Observer1 get the update:" << p_subject_->GetState() << endl;
}
};
//具體觀察者2
class Observer2 : public Observer
{
public:
Observer2(Subject *p_subject) : Observer(p_subject) {}
void Update() override {
cout << "Observer2 get the update:" << p_subject_->GetState() << endl;
}
};
//具體被觀察者
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver) override {
observer_list_.push_back(pObserver);
}
void Detach(Observer *pObserver) override {
observer_list_.remove(pObserver);
}
void Notify() override ;
};
//核心操作:循環通知所有觀察者
void ConcreteSubject::Notify() {
auto it = observer_list_.begin();
while (it != observer_list_.end()) {
(*it++)->Update();
}
}
int main()
{
// 創建被觀察者
Subject *p_subject = new ConcreteSubject();
// 創建觀察者
Observer *p_observer1 = new Observer1(p_subject);
Observer *p_observer2 = new Observer2(p_subject);
// 改變狀態
p_subject->SetState(2);
// 註冊觀察者
p_subject->Attach(p_observer1);
p_subject->Attach(p_observer2);
p_subject->Notify();
// 註銷觀察值
p_subject->Detach(p_observer1);
p_subject->SetState(3);
p_subject->Notify();
delete p_observer1;
delete p_observer2;
delete p_subject;
}