设计模式理解:观察者模式
? ? 觀察者模式,對象行為型模式,又稱為依賴模式,發布訂閱模式。當一個對象狀態發生改變時,通過通知的形式,讓依賴于它的多個對象自動得進行更新。例如JAVA中的Listener ,C#中的Event。?
? ? 在合理的依賴關系中,下層結構不應該依賴于上層結構。但是在某些情況中,需要從底層的方法將上層的對象進行更新。一般的解決方式是將上層的對象以參數的形式不斷的傳遞到底層,而觀察者模式中,在底層方法里發出通知到接口中,而上層對象通過對接口的實現,將內容更新至其屬性里。
? ? 在案例中,有一個復制大文件時更新進度條進度的 需求。
class FileCopy{string srcpath;string dispath;ProgressBar * progressBar;public:FileCopy(string s,string d,ProgressBar & p):filepath(s),dispath(d),progressBar(p){}void copy(){//1 創建目標文件,讀取源文件disfile =createfile(dispath)srcfile =readfile(srcpath)....double totalsize = srcfile.totalsize();double sum = 0;while(content=srcfile.readline()){//按行寫入文件disfile.write(content);//寫文件后更新進度條sum +=content.size;progressBar->setvalue(sum/totalsize);}} }//------------界面--------------- class MainForm { ProgressBar bar; public:void button_Click(){ //.....FileCopy fc(srcfile,disfile,&bar);fc.copy();} }上述的代碼設計中,雖然實現了功能,但弊端是顯而易見的。
1.下層的FileCopy 依賴于上層 mainform的對象,FileCopy類無法復用于控制臺,網頁等其他項目工程
2.當需求變為“不用進度條顯示進度,改用Label直接以百分比展示進度”,那么自上而下的要把對象類型進行改造,并且progressBar有setvalue方法,而其他控件可能沒有。改造起來復雜度高。
3.這個方法當前只能支持一個進度條,如果想要支持多個不同的控件,那就只能要擴展參數,可維護性會變差。
在如下代碼中,展示了以觀察者模式的模式設計實現相同的需求。擺脫了底層依賴于高層,達到穩定與變化的分離,可以將類和接口原封不動地應用與其他項目。提高的了代碼的復用性,易維護性,易擴展性。 以通知地形式,開放通知接口,讓應用程序去實現該接口達到更新進度條的目的。
//通知接口 class INotice{virtual void notify(double)=0; } class FileCopy{string srcpath;string dispath;vector<INotice*> notices; //通知對象集合public:FileCopy(string s,string d):filepath(s),dispath(d){}void add(INotice * in){notices.push_back(in);}void copy(){//1 創建目標文件,讀取源文件disfile =createfile(dispath)srcfile =readfile(srcpath)....double totalsize = srcfile.totalsize();double sum = 0;while(content=srcfile.readline()){//按行寫入文件disfile.write(content);//寫文件后更新進度條sum +=content.size;//給所有依賴發出通知copynotify(sum/totalsize);}}protected:void copynotify(double value){for(notice :notices){notice->notify(value);}} }//------------界面,實現INotice接口方法--------------- class MainForm:public INotice{ ProgressBar bar; public:void button_Click(){ //.....ChildForm *cform = new ChildForm ();FileCopy fc(srcfile,disfile);fc.add(this);fc.add(cform );fc.copy();}virtual void notify(double value){bar.setvalue(value);} }class ChildForm:public INotice{Label label;virtual void notify(double value){bar.settitle(value);} }?
?
總結
以上是生活随笔為你收集整理的设计模式理解:观察者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式理解:策略模式
- 下一篇: asp.net ajax控件工具集 Au