設計模式—觀察者模式(十)

        軟件領域中的設計模式的重要性不言而喻。設計模式中運用了面向對象編程語言的重要特性:封裝、繼承、多態。雖然知道這些特性的定義但是並沒有做到真正的理解,這樣特性有什麼作用?用於什麼場合中等等問題,帶着疑問開始學習設計模式,主要參考《大話設計模式》和《設計模式:可複用面向對象軟件的基礎》兩本書。

1. 概述

  有時被稱作發佈/訂閱模式,觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。

2. 解決的問題

  將一個系統分割成一個一些類相互協作的類有一個不好的副作用,那就是需要維護相關對象間的一致性。我們不希望爲了維持一致性而使各類緊密耦合,這樣會給維護、擴展和重用都帶來不便。觀察者就是解決這類的耦合關係的。

3. 模式中的角色

  3.1 抽象主題(Subject):它把所有觀察者對象的引用保存到一個聚集裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。

  3.2 具體主題(ConcreteSubject):將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。

  3.3 抽象觀察者(Observer):爲所有的具體觀察者定義一個接口,在得到主題通知時更新自己。

  3.4 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題狀態協調。


//例:
#include <string>
#include <iostream>
#include <vector>
using namespace std;

class SecretaryBase;
//抽象觀察者
class CObserverBase
{
protected:
	string name;
	SecretaryBase* sub;
public:
	//參數列表爲SecretaryBase* 不是具體類,這就是針對抽象編程,減少真實類的耦合
	CObserverBase(string strname, SecretaryBase* strsub)
	{
		name = strname;
		sub = strsub;
	}
	virtual void Update() = 0;
};
//具體的觀察者,看股票的
class StockObserver : public CObserverBase
{
public:
	StockObserver(string strname, SecretaryBase* strsub) : CObserverBase(strname, strsub){}
	virtual void Update();
};

//具體觀察者,看NBA的
class NBAObserver : public CObserverBase
{
public:
	NBAObserver(string strname, SecretaryBase* strsub) : CObserverBase(strname, strsub){}
	virtual void Update();
};


//抽象類 通知者
class SecretaryBase
{
public:
	string action;
	vector<CObserverBase*> observers;
public:
	//針對抽象編程,減少真實類的耦合
	virtual void Add(CObserverBase* observer) = 0;
	virtual void Notify() = 0;
};

//具體通知者
class Secretary :public SecretaryBase
{
public:
	
	void Add(CObserverBase* ob)
	{
		observers.push_back(ob);
	}
	void Notify()
	{
		for (CObserverBase* p : observers)
			p->Update();
	}
};

void StockObserver::Update()
{
	cout << name << ":" << sub->action << ",不要玩股票了,要開始工作了" << endl;
}
void NBAObserver::Update()
{
	cout << name << ":" << sub->action << ",不要看NBA了,老闆來了" << endl;
}


//客戶端:
int main()
{
	SecretaryBase *p = new Secretary();  //創建觀察者

	//被觀察的對象
	CObserverBase *s1 = new NBAObserver("小李", p);
	CObserverBase *s2 = new StockObserver("小趙", p);
	//加入觀察隊列
	p->Add(s1);
	p->Add(s2);
	//事件
	p->action = "老闆來了";
	//通知
	p->Notify();

	return 0;
}


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