本文參考文獻::GeekBand課堂內容,授課老師:李建忠設計模式
:網絡資料: http://blog.csdn.net/hguisu/article/details/7556625網絡
本文僅做爲本身的學習筆記,不表明權威,由於是初學,有錯誤煩請你們指正,謝謝。函數
觀察者模式(有時又被稱爲發佈-訂閱Subscribe>模式、模型-視圖View>模式、源-收聽者Listener>模式或從屬者模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。post
--------360百科定義學習
如上圖所示:觀察者模式包含以下角色:ui
目標(Subject): 目標知道它的觀察者。能夠有任意多個觀察者觀察同一個目標。 提供註冊和刪除觀察者對象的接口。this
//目標: 目標知道它的觀察者。能夠有任意多個觀察者觀察同一個目標。 提供註冊和刪除觀察者對象的接口。 Class Form { public: virtual void Attach(FileSpliter* observer);//註冊觀察者 virtual void Detach(FileSpliter* observer);//釋放觀察者 virtual void Notify();//通知全部註冊的觀察者 interface SplObserver { virtual void Update(Form *) = 0; //觀察者進行更新狀態 }; }
具體目標(ConcreteSubject): 將有關狀態存入各ConcreteObserver對象。spa
//具體目標(MainForm): 將有關狀態存入各MainForm對象 class MainForm : public Form { public: /** * 釋放觀察者 */ virtual void Attach(FileSpliter* observer) { _observers->Append(observer); } /** * 註冊觀察者 */ virtual void Detach(FileSpliter* observer) // { _observers->Remove(observer); }; /** * 通知全部觀察者 */ virtual void Notify() { for obs in _observers //遍歷 { if (observers->getState() == this->State) { obs->Update(this); } } }; //設置狀態 void Button1_Click(bool State) { this->State = State; //狀態改變 Notify(); } protected: MainForm() {} private: TestBox* txtFilePath; TextBox* txtFileNumber; ProgressBar* progressBar; List<FileSpliter*> *_observers; };
觀察者(Observer): 爲那些在目標發生改變時需得到通知的對象定義一個更新接口。當它的狀態發生改變時, 向它的各個觀察者發出通知。.net
/** * 抽象觀查者 * */ class FileSplitter { public: virtual void Split() = 0; virtual void Update(MainForm*) = 0; virtual ~FileSplitter() {} protected: virtual void onProgress(float value) { List<FileSpliter*>::iterator itor = _observers.begin(); while (itor != _observers.end()) (*itor)->DisplayProgress(value); //更新進度條 itor++; } void DisplayProgress(int value) { progressBar->setValue(value); } } private: string filePath; int fileNumber; bool State; };
具體觀察者(ConcreteObserver): 維護一個指向ConcreteSubject對象的引用。存儲有關狀態,這些狀態應與目標的狀態保持一致。實現Observer的更新接口以使自身狀態與目標的狀態保持一致。設計
//具體觀察者1 class Spliter1 : public FileSplitter { public: Spliter1(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter1() { _subject->State = false _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //一、打開文件filePath //二、把文件分割成fileNumber個文件 //三、DisplayProgress重載,以1的方式更新進度(如進度條) DisplayProgress(value); } private: bool State; MainForm* _subject; }; //具體觀察者2 class Spliter2 : public FileSplitter { public: Spliter2(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter2() { _subject->State = false; _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //一、打開文件filePath //二、把文件分割成fileNumber個文件 //三、DisplayProgress重載,以2的方式更新進度(如控制檯...) DisplayProgress(value); private: MainForm* _subject; bool State; }; //具體觀察者3 class Spliter3 : public FileSplitter { public: Spliter3(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter3() { _subject->State = false; _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //一、打開文件filePath //二、把文件分割成fileNumber個文件 //三、DisplayProgress重載,以3的方式更新進度(如百分比) DisplayProgress(value); } private: MainForm* _subject; bool State; };
main函數
nt main() { MainForm* mf = new MainForm(); Spliter1* sp1 = new Spliter1(mf); Spliter2* sp2 = new Spliter2(mf); Spliter3* sp3 = new Spliter3(mf); return 0; }
一、經過Observer模式,把一對多對象之間的通知依賴關係的變得更爲鬆散,大大地提升了程序的可維護性和可擴展性,也很好的符合了開放-封閉原則。
二、觀察者模式符合開閉原則,開閉原則是指一個軟件實體應該對擴展開放,對修改關閉。也就是說軟件實體必須是在不被修改的狀況下被擴展。模板方法模式意圖是由抽象父類控制頂級邏輯,並把基本操做的實現推遲到子類去實現,這是經過繼承的手段來達到對象的複用。
三、
模板方法模式與對象的封裝性,面向對象的三大特性:繼承,封裝,多態。 對象有內部狀態和外部的行爲。封裝是爲了信息隱藏,經過封裝來維護對象內部數據的完整性。使得外部對象不可以直接訪問一個對象的內部狀態,而必須經過恰當的方法才能訪問。在C++中,採用給對象屬性和方法賦予指定的修改符(public、protected、private)來達到封裝的目的,使得數據不被外部對象惡意的訪問及方法不被錯誤調用導形成破壞對象的封裝性。