Observer/Event觀察者模式(C++)


動機: 在軟件構建過程中,我們需要爲某些對象建立一種“通知依賴關係”--一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關係過於緊密,將使軟件不能很好地抵禦變化。
使用面向對象技術,可以將這種依賴關係弱化,並形成一種穩定的依賴關係。從而實現軟件體系結構的鬆耦合。

鬆耦合可以體現在下面幾種情況:
1)一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這些方面封裝在獨立的對象中使它們可以各自獨立地改變和複用。
2)一個對象的改變將導致其他一個或多個對象也發生改變,而不需要知道具體有多少對象、這些對象是誰

GOF定義:定義對象間的一種一對多(變化)的依賴關係,以便當一個對象(Subject)的狀態發生改變時,所有依賴於它的對象(Observer)都得到通知並自動更新。


舉例: 對同一組數據進行統計分析時候, 我們希望能夠提供多種形式的表示 (例如以表格進行統計顯示、柱狀圖統計顯示、百分比統計顯示等)。這些表示都依賴於同一組數據, 我們當然需要當數據改變的時候, 所有的統計的顯示都能夠同時改變。 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章