C++設計形式編程中的不雅察者形式應用示例。本站提示廣大學習愛好者:(C++設計形式編程中的不雅察者形式應用示例)文章只能為提供參考,不一定能成為您想要的結果。以下是C++設計形式編程中的不雅察者形式應用示例正文
概述:
比來中國股市起升沉伏,固然了升沉就用商機,小明發明商機效果斷想入市,買入了中國證券,他想在電腦客戶端上,網頁上,手機上,iPad上都可以檢查到該證券的及時行情,這類情形下我們應當怎樣設計我們的軟件呢?我們可以如許:小明的一切客戶端上都定閱中國證券這個股票,只需股票一有變更,一切的客戶端都邑被告訴到而且被主動更新。
這就是我們的不雅察者形式,她界說對象間的一種一對多的依附關系,當一個對象的狀況產生轉變時, 一切依附於它的對象都獲得告訴並被主動更新。
類圖:
可以看出,在這個不雅察者形式的完成裡有上面這些腳色:
籠統主題(Subject)腳色:主題腳色把一切對不雅察考對象的援用保留在一個集合裡,每一個主題都可以有任何數目的不雅察者。籠統主題供給一個接口,可以增長和刪除不雅察者對象,主題腳色又叫做籠統被不雅察者(Observable)腳色,普通用一個籠統類或許一個接話柄現。
籠統不雅察者(Observer)腳色:為一切的詳細不雅察者界說一個接口,在獲得主題的告訴時更新本身。這個接口叫做更新接口。籠統不雅察者腳色普通用一個籠統類或許一個接話柄現。在這個表示性的完成中,更新接口只包括一個辦法(即Update()辦法),這個辦法叫做更新辦法。
詳細主題(ConcreteSubject)腳色:將有關狀況存入詳細現察者對象;在詳細主題的外部狀況轉變時,給一切掛號過的不雅察者收回告訴。詳細主題腳色又叫做詳細被不雅察者腳色(Concrete Observable)。詳細主題腳色平日用一個詳細子類完成。
詳細不雅察者(ConcreteObserver)腳色:存儲與主題的狀況自恰的狀況。詳細現察者腳色完成籠統不雅察者腳色所請求的更新接口,以便使自己的狀況與主題的狀況相調和。假如須要,詳細現察者腳色可以保留一個指向詳細主題對象的援用。詳細不雅察者腳色平日用一個詳細子類完成。
從詳細主題腳色指向籠統不雅察者腳色的分解關系,代表詳細主題對象可以有隨意率性多個對籠統不雅察者對象的援用。之所以應用籠統不雅察者而不是詳細不雅察者,意味著主題對象不須要曉得援用了哪些ConcreteObserver類型,而只曉得籠統Observer類型。這就使得詳細主題對象可以靜態地保護一系列的對不雅察者對象的援用,並在須要的時刻挪用每個不雅察者共有的Update()辦法。這類做法叫做"針對籠統編程"。
概念
不雅察者形式是講有一個目的,浩瀚個不雅察者去“不雅察”目的。目的是目的籠統類的一個派生類,不雅察者是不雅察者籠統類的一個派生類。當目的類的數據轉變,一切對應的不雅察者對應去更新本身的狀況
可使用的情形:好比有一個世界時鐘法式,有多個圖形時鐘去顯示好比北京時區,巴黎時區,等等。假如設置一個北京時光,那末其他時鐘圖形都須要更新(加上或許減去時差值)。典范的圖形界面設計到處可見,一個溫度法式,在溫度濕度等前提轉變時,要更新多種顯示圖形來出現。
實例
應用時,起首界說一個Subject的類對象,然後再界說多個Observer類(派生類)對象,每一個Observer對象指定本身被注冊到哪一個Subject對象內。
示例:
#include<vector> #include<iostream> #include<string> using namespace std; class Subject; class Observer{ //不雅察者籠統類 public: virtual void update(Subject *base)=0; protected: Subject * _subject; }; class Subject{ //目的籠統類 public: string s1; //數據值,可以作為公有數據,然後界說一個托言去前往值,這裡為了省事 int i1; //數據值 void regiObserver(Observer *obs){ _observer.push_back(obs); cout<<"已注冊"<<endl; } void deleObserver(Observer *obs){ _observer.pop_back(); } void notify(){ //更新一切的不雅察者 vector<Observer *>::iterator it; for(it = _observer.begin(); it != _observer.end(); it++) (*it)->update(this); } private: vector<Observer *> _observer; //不雅察者容器 }; class FSubject:public Subject{ public: void set(string s,int i){ s1 = s; i1 = i; notify(); //告訴不雅察者。主函數的履行次序曾經包管了一切的不雅察者都曾經進入容器內 } }; class FObserver :public Observer{ //第一個不雅察者派生類 public: FObserver(Subject *base):Observer(){ _subject = base; _subject->regiObserver(this); } void update(Subject *base){ s1 = base->s1; i1 = base->i1; display(); } void display(){ cout<<"更新值,第一個\n"<<s1<<endl; cout<<i1<<endl; } private: string s1; int i1; }; class SObserver:public Observer{ //第二個不雅察者派生類 public: SObserver(Subject * base){ _subject = base; _subject->regiObserver(this); } void update(Subject *base){ s1 = base->s1; i1 = base->i1; display(); } void display(){ cout<<"更新值,第二個\n"<<s1<<endl; cout<<i1<<endl; } private: string s1; int i1; }; int main() { FSubject * sub = new FSubject; FObserver * one = new FObserver(sub); SObserver * two = new SObserver(sub); sub->set("ok",3); return 0;
}
Subject 類中的容器對象保護者一切對不雅察者的援用,目標是在notify中去更新一切的不雅察者,即經由過程遍歷去挪用不雅察者->update()。
不雅察者中的update()感化是完成不雅察者須要完成的事,好比在上例中,去更新本身保留的正本值,然後並顯示出來。
Observer類中有一個Subject指針異常主要,在不雅察者的派生類的結構函數,須要去把本身的this傳遞曩昔停止注冊。
Observer中有和Subject異樣的數據,也能夠設置為部分變量,僅僅是完成不雅察者須要做的事就行,而不用存儲。