青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

設(shè)計模式之觀察者模式

一、什么是觀察者模式

     Observer模式也叫觀察者模式,是由GoF提出的23種軟件設(shè)計模式的一種。Observer模式是行為模式之一,它的作用是當(dāng)一個對象的狀態(tài)發(fā)生變化時,能夠自動通知其他關(guān)聯(lián)對象,自動刷新對象狀態(tài)。

  觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,用戶界面可以作為一個觀察者,業(yè)務(wù)數(shù)據(jù)是被觀察者,用戶界面觀察業(yè)務(wù)數(shù)據(jù)的變化,發(fā)現(xiàn)數(shù)據(jù)變化后,就顯示在界面上。面向?qū)ο笤O(shè)計的一個原則是:系統(tǒng)中的每個類將重點(diǎn)放在某一個功能上,而不是其他方面。一個對象只做一件事情,并且將他做好。觀察者模式在模塊之間劃定了清晰的界限,提高了應(yīng)用程序的可維護(hù)性和重用性。

 

  觀察者模式有很多實(shí)現(xiàn)方式,從根本上說,該模式必須包含兩個角色:觀察者和被觀察對象。在剛才的例子中,業(yè)務(wù)數(shù)據(jù)是被觀察對象,用戶界面是觀察者。觀察者和被觀察者之間存在“觀察”的邏輯關(guān)聯(lián),當(dāng)被觀察者發(fā)生改變的時候,觀察者就會觀察到這樣的變化,并且做出相應(yīng)的響應(yīng)。如果在用戶界面、業(yè)務(wù)數(shù)據(jù)之間使用這樣的觀察過程,可以確保界面和數(shù)據(jù)之間劃清界限,假定應(yīng)用程序的需求發(fā)生變化,需要修改界面的表現(xiàn),只需要重新構(gòu)建一個用戶界面,業(yè)務(wù)數(shù)據(jù)不需要發(fā)生變化。

 

  “觀察”不是“直接調(diào)用”

  實(shí)現(xiàn)觀察者模式的時候要注意,觀察者和被觀察對象之間的互動關(guān)系不能體現(xiàn)成類之間的直接調(diào)用,否則就將使觀察者和被觀察對象之間緊密的耦合起來,從根本上違反面向?qū)ο蟮脑O(shè)計的原則。無論是觀察者“觀察”觀察對象,還是被觀察者將自己的改變“通知”觀察者,都不應(yīng)該直接調(diào)用。

 

  實(shí)現(xiàn)觀察者模式的形式

  實(shí)現(xiàn)觀察者模式有很多形式,比較直觀的一種是使用一種“注冊——通知——撤銷注冊”的形式。

 

   實(shí)現(xiàn)觀察者模式例子

       下面是C++的實(shí)現(xiàn),在C++實(shí)現(xiàn)中,C++中沒有接口的概念,但是可以用抽象類類代替Java或C#中的接口,在C++中抽象類中從派生類中抽象出來的函數(shù)(方法),必須定義成純虛函數(shù),這樣在后面的使用中才可以通過基類的指針來訪問這些函數(shù),面向?qū)ο蟮恼Z言中有個特點(diǎn),多態(tài)只能訪問兩者中共有的部分。

  1
  2#include "stdafx.h"
  3#include <string>
  4#include <vector>
  5#include<list>
  6#include<iostream>
  7using namespace std;
  8
  9class Observer;
 10class Subject
 11{
 12public:
 13    //注冊
 14     virtual void attach(Observer *o)=0;
 15     //撤銷
 16     virtual void dettach(Observer *o)=0;
 17     //發(fā)送消息,更新觀察者數(shù)據(jù)
 18     virtual void change()=0;
 19     //更新數(shù)據(jù)
 20     virtual void setWeather(string str)=0;
 21     //獲取數(shù)據(jù)
 22     virtual string getWeather()=0;
 23}
;
 24
 25class Observer
 26{
 27public:
 28    //獲得觀察者的名字,用于后面dettach撤銷操作
 29     virtual string getName()=0;
 30     //更新數(shù)據(jù),用于被觀察者調(diào)用
 31     virtual void update(Subject *s)=0;
 32}
;
 33
 34//被觀察者
 35class Earth: public Subject
 36{
 37private:
 38    //數(shù)據(jù)
 39     string weather;
 40     //存放觀察者的list,因?yàn)镺bserver是個抽象類,
 41     //所以不能聲明成 list<Observer >* l
 42     list<Observer* >* l;//指針 
 43public:
 44    //初始化存放觀察者的容器
 45     Earth()
 46     {
 47        l = new list<Observer*>;
 48     }
;
 49     //別忘了釋放資源
 50    ~Earth()
 51    {
 52        delete l;
 53    }
;
 54    //注冊觀察者
 55     void attach(Observer *o)
 56     {
 57        this->l->push_back(o);
 58     }
;
 59    
 60     //注銷觀察者
 61      void dettach(Observer *o)
 62     {
 63         for(list<Observer*>::iterator it=l->begin();it!=l->end();++it)
 64         {
 65             //通過string來進(jìn)行查找,其他通過指針怎么判斷相等比較困難
 66             if( (*it)->getName() == o->getName())
 67             {
 68                 l->remove(*it);
 69                 break;
 70             }

 71         }

 72     }
;
 73
 74    //通知并更新觀察者
 75     void change()
 76     {
 77          for(list<Observer*>::iterator it=l->begin();it!=l->end();++it)
 78          {
 79            (*it)->update(this);
 80          }

 81     }
;
 82
 83     //更新數(shù)據(jù)
 84     void setWeather(string str)
 85     {
 86          this->weather=str;
 87          change();
 88     }
;
 89
 90     string getWeather()
 91     {
 92         return this->weather;
 93     }
;
 94
 95}
;
 96
 97class Satellite:public Observer
 98{
 99private:
100     string name;
101public:
102     Satellite(string str)
103     {
104          name=str;
105     }

106     string getName()
107     {
108         return name;
109     }
;
110     //更新數(shù)據(jù)
111     void update(Subject *s)
112     {
113         cout<<this->getName()+" "+s->getWeather()<<endl;
114     }

115}
;
116
117
118
119int _tmain(int argc, _TCHAR* argv[])
120{
121     Earth e;
122     Satellite *s1 = new Satellite("風(fēng)云一號");
123     Satellite *s2 = new Satellite("風(fēng)云二號");
124     Satellite *s3 = new Satellite("風(fēng)云三號");
125     Satellite *s4 = new Satellite("風(fēng)云四號");
126     e.attach(s1);
127     e.attach(s2);
128     e.attach(s3);
129     e.attach(s4);
130     e.setWeather("fine");
131     e.setWeather("rain");
132     //注銷s3
133     e.dettach(s3);
134     e.setWeather("fine");
135     e.setWeather("rain");
136
137
138    return 0;
139}

140
141

以上文字參照http://blog.csdn.net/preciousboy/article/details/6230467,對其代碼進(jìn)行修改在vs2008中編譯調(diào)試通過。
結(jié)果運(yùn)行為:


這里要注意的幾個問題是?
1.被觀察者怎么去通知觀察者數(shù)據(jù)已經(jīng)更新?--本例子中是通過void change()函數(shù)來實(shí)現(xiàn)的;
2.在此模式中你可以從被觀察者處push或者pull數(shù)據(jù),我們認(rèn)為push的方式是正確的。
3.觀察者模式定義了一對多的關(guān)系
4.有多個觀察者時不依賴于特定的通知次序。
5.java的MVC模式就采用此模式實(shí)現(xiàn)。

posted on 2012-05-01 11:47 sheng 閱讀(664) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導(dǎo)航

<2012年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

統(tǒng)計

常用鏈接

留言簿(1)

隨筆檔案

收藏夾

同行

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩亚洲欧美精品| 国产精品人人做人人爽人人添| 亚洲一区二区三区免费观看| 久久久久免费视频| 欧美一区二区三区在线观看视频| 欧美久色视频| 亚洲丰满在线| 精品不卡在线| 欧美一区二区三区在线看 | 久久人人看视频| 国产精品亚洲一区二区三区在线| 亚洲人成高清| 欧美色网在线| 国产精品亚发布| 国产一区二区看久久| 国产精品自拍网站| 亚洲欧美日韩另类| 欧美三级在线视频| 99天天综合性| 午夜国产欧美理论在线播放| 国产精品a久久久久| 99国产成+人+综合+亚洲欧美| 日韩视频在线永久播放| 欧美国产在线电影| 日韩午夜中文字幕| 亚洲欧美精品| 国产精品日韩欧美| 午夜精品久久久久久久蜜桃app| 欧美伊人影院| 国产欧美日韩在线播放| 午夜天堂精品久久久久| 久久久91精品| 亚洲福利在线观看| 欧美激情精品久久久久久变态| 亚洲欧洲中文日韩久久av乱码| 99re视频这里只有精品| 国产精品chinese| 性欧美精品高清| 久热成人在线视频| 亚洲精品免费一区二区三区| 欧美日韩一区二区三区在线看 | 一本色道久久99精品综合| 欧美三级午夜理伦三级中文幕| 亚洲一区欧美一区| 久久夜色精品国产噜噜av| 亚洲电影免费在线观看| 欧美日韩视频在线| 亚洲欧美一区二区原创| 欧美+日本+国产+在线a∨观看| 亚洲日本中文字幕免费在线不卡| 欧美日韩在线视频一区二区| 亚洲欧美国产va在线影院| 麻豆精品在线视频| 99re66热这里只有精品4| 国产精品视频一区二区三区 | 免费国产自线拍一欧美视频| 亚洲乱码久久| 久久久噜噜噜久久狠狠50岁| 亚洲精品国产精品国自产观看| 欧美视频国产精品| 久久日韩粉嫩一区二区三区| 日韩亚洲在线观看| 蜜臀va亚洲va欧美va天堂 | 欧美 日韩 国产一区二区在线视频| 亚洲欧洲视频在线| 国产精品一区二区三区乱码| 久久在线免费| 亚洲欧美综合另类中字| 亚洲黄网站在线观看| 久久久久一区二区三区四区| 一区二区三区四区五区视频| 精品999网站| 国产精品三级久久久久久电影| 欧美xart系列高清| 欧美一区二区三区视频免费播放 | 中文久久精品| 91久久久久| 国产一区二区中文| 国产精品二区在线| 欧美日本在线视频| 麻豆av一区二区三区| 欧美专区亚洲专区| 亚洲一区二区三区在线视频| 亚洲欧洲精品一区二区三区不卡 | 欧美在线观看视频一区二区三区| 99精品国产在热久久婷婷| 国产一区二区精品久久91| 欧美三级午夜理伦三级中视频| 麻豆精品在线观看| 久久精品在线视频| 午夜精品久久久久久| 亚洲视频网在线直播| 亚洲看片免费| 亚洲国产精品成人久久综合一区| 久久嫩草精品久久久久| 欧美制服丝袜| 亚洲一二三区在线观看| 亚洲激情一区二区| 伊人春色精品| 黑人极品videos精品欧美裸| 国产精品美女午夜av| 欧美日韩亚洲视频| 欧美日韩第一页| 欧美日韩免费一区| 欧美日韩在线播放三区四区| 欧美日韩免费一区二区三区| 欧美日韩国产在线| 欧美日韩少妇| 国产精品二区三区四区| 国产精品久久久久婷婷| 国产精品欧美久久| 国产精品综合av一区二区国产馆| 国产精品天天摸av网| 国产精品夜夜夜一区二区三区尤| 国产精品卡一卡二卡三| 国产精品视频网址| 国产一区二区日韩精品| 影音国产精品| 亚洲精品一区二区在线观看| 精品999网站| 亚洲日韩欧美一区二区在线| 日韩午夜电影av| 亚洲免费视频观看| 欧美制服丝袜| 免费高清在线一区| 亚洲国产视频一区二区| 99日韩精品| 欧美一区亚洲二区| 欧美成年人网| 国产精品久久久久久久久久三级 | 永久免费视频成人| 亚洲三级免费电影| 亚洲一区二区伦理| 久久久亚洲欧洲日产国码αv| 欧美大片在线观看一区| 日韩网站在线观看| 欧美一区亚洲| 欧美经典一区二区三区| 国产精品一区二区你懂的| 伊人春色精品| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美专区在线播放| 亚洲大胆女人| 亚洲女女女同性video| 久久综合一区二区| 国产精品久久久久天堂| 亚洲国产精品久久久久久女王| 日韩一本二本av| 久久久久成人精品免费播放动漫| 亚洲国产成人久久综合| 亚洲一二三区在线| 欧美激情亚洲自拍| 韩国三级电影久久久久久| 在线综合视频| 欧美国产成人精品| 午夜日韩激情| 欧美视频日韩视频在线观看| 尤物yw午夜国产精品视频明星| 亚洲小说区图片区| 亚洲二区免费| 久久国产88| 国产精品久在线观看| 日韩亚洲欧美成人| 另类春色校园亚洲| 亚洲欧美综合另类中字| 欧美日韩精品不卡| 亚洲日本va午夜在线影院| 久久精品最新地址| 亚洲一区二区三区精品动漫| 欧美伦理a级免费电影| 在线观看欧美| 久久午夜电影网| 性色av一区二区三区在线观看| 欧美日韩免费在线视频| 亚洲乱码国产乱码精品精天堂| 另类亚洲自拍| 欧美在线黄色| 国产三级精品三级| 午夜精彩国产免费不卡不顿大片| 亚洲精品一区二区三区四区高清| 久久综合伊人77777尤物| 精品电影在线观看| 久久综合九色综合久99| 香蕉成人啪国产精品视频综合网| 国产精品三级视频| 亚洲欧洲99久久| 亚洲女人av| 国产亚洲精品久久久久婷婷瑜伽| 欧美一级黄色录像| 午夜精品久久久久久99热| 国产精品激情电影| 亚洲欧美综合精品久久成人| 亚洲永久免费av| 国产视频在线观看一区二区| 久久精品欧美日韩| 久久久久免费视频| 亚洲国产精品va在线观看黑人| 欧美激情在线有限公司| 欧美激情精品久久久| 在线亚洲自拍|