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

eryar

PipeCAD - Plant Piping Design Software.
PlantAssistant - Translate AVEVA RVM/SP3D VUE to glTF, STEP, etc.
posts - 606, comments - 590, trackbacks - 0, articles - 0

[轉]設計模式-Observer

Posted on 2012-10-19 22:36 eryar 閱讀(1349) 評論(0)  編輯 收藏 引用

設計模式-Observer

1. 解決的問題:

   假如現在要編寫一個天氣預報的公布欄, 公布欄有兩種顯示方式, 一種是圖像方式顯示, 一種是表格形式顯示.

2. 問題分析:

   應該根據數據與現實分離的原則將天氣預報數據和現實形式分別封裝起來,

   今后可能增加其他的顯示形式;

   天氣預報數據發生變化后,需要對所有的顯示形式進行更新.

3. UML圖與代碼實現:

1)用Push的方式更新Observer數據, 通過Subject對Observer進行注冊:

  1: //這個例子中WeatherData就是Subject, 而WeatherView則是Observer,
  2: //這里WeatherView中沒有包含到WeatherData的引用,
  3: //因此這里是Subject用push的方法向Observer發送數據;
  4: //并且注冊和反注冊Observer的時候都是由Subject(WeatherData)執行的
  5: 
  6: #include <iostream>
  7: #include <vector>
  8: #include <algorithm>
  9: 
 10: using namespace std;
 11: 
 12: class WeatherData;
 13: 
 14: class WeatherView
 15: {
 16: public:
 17:     void Update(int temp, int hum)
 18:     {
 19:         temperature = temp;
 20:         humidity = hum;
 21:     };
 22:     virtual void Display()
 23:     {
 24:         cout << "temperature = " << temperature << ", humidity = " << humidity << endl;
 25:     }
 26: 
 27: private:
 28: 
 29:     int temperature;
 30:     int humidity;
 31: };
 32: 
 33: class GraphicView: public WeatherView
 34: {
 35: public:
 36:     void Display()
 37:     {
 38:         cout << "====--Weather Report With Graphic Format--===="<< endl;
 39:         WeatherView::Display();
 40:     }
 41: };
 42: 
 43: class TableView: public WeatherView
 44: {
 45: public:
 46:     void Display()
 47:     {
 48:         cout << "====--Weather Report With Table Format--===="<< endl;
 49:         WeatherView::Display();
 50:     }
 51: };
 52: 
 53: class WeatherData
 54: {
 55: public:
 56:     void SetWeahterData(int temp, int hum)
 57:     {
 58:         temperature = temp;
 59:         humidity = hum;
 60:         NotifyObservcer();
 61:     }
 62: 
 63:     void RegisterObserver(WeatherView* obs)
 64:     {
 65:         obsList.push_back(obs);
 66:     }
 67: 
 68:     void RemoveObserver(WeatherView* obs)
 69:     {
 70:         vector<WeatherView*>::iterator it;
 71:         it = find(obsList.begin(), obsList.end(), obs);
 72:         if (it != obsList.end())
 73:             obsList.erase(it);
 74:     }
 75: 
 76: private:
 77:     vector<WeatherView*> obsList;
 78:     int temperature;
 79:     int humidity;
 80:     void NotifyObservcer()
 81:     {
 82:        vector<WeatherView*>::iterator it;
 83:        for(it = obsList.begin(); it < obsList.end(); it++)
 84:        {
 85:            (*it)->Update(temperature, humidity);
 86:        }
 87:     }
 88: };
 89: 
 90: 
 91: int main()
 92: {
 93:     WeatherData *wd = new WeatherData();
 94:     GraphicView *gv = new GraphicView();
 95:     TableView *tv = new TableView();
 96: 
 97:     wd->RegisterObserver(gv);
 98:     wd->RegisterObserver(tv);
 99:     wd->SetWeahterData(23,45);
100:     gv->Display();
101:     tv->Display();
102: 
103:     wd->RemoveObserver(gv);
104:     wd->SetWeahterData(67,89);
105:     gv->Display();
106:     tv->Display();
107: 
108:     return 0;
109: }
2)用Pull的方式更新Observer數據, Observer自己進行注冊:

  1: #ifndef WEATHERDATA_HPP_INCLUDED
  2: #define WEATHERDATA_HPP_INCLUDED
  3: #include <iostream>
  4: #include <vector>
  5: 
  6: #include "WeatherView.hpp"
  7: 
  8: class WeatherData
  9: {
 10: public:
 11:     void SetWeahterData(int temp, int hum)
 12:     {
 13:         temperature = temp;
 14:         humidity = hum;
 15:         NotifyObservcer();
 16:     }
 17: 
 18:     int GetTemperature()
 19:     {
 20:         return temperature;
 21:     }
 22: 
 23:     int GetHumidty()
 24:     {
 25:         return humidity;
 26:     }
 27: 
 28:     void RegisterObserver(WeatherView* obs);
 29:     void RemoveObserver(WeatherView* obs);
 30: 
 31: private:
 32:     vector<WeatherView*> obsList;
 33:     int temperature;
 34:     int humidity;
 35:     void NotifyObservcer();
 36: };
 37: 
 38: #endif

=================

  1: #ifndef WEATHERVIEW_HPP_INCLUDED
  2: #define WEATHERVIEW_HPP_INCLUDED
  3: 
  4: #include <iostream>
  5: #include <vector>
  6: #include <algorithm>
  7: 
  8: 
  9: class WeatherData;
 10: 
 11: using namespace std;
 12: 
 13: class WeatherView
 14: {
 15: public:
 16:     WeatherView(WeatherData* wd);
 17: 
 18:     void Update();
 19:     void Register();
 20:     void Unregister();
 21: 
 22:     virtual void Display()
 23:     {
 24:         cout << "temperature = " << temperature << ", humidity = " << humidity << endl;
 25:     }
 26: 
 27: private:
 28:     WeatherData* wd;
 29:     int temperature;
 30:     int humidity;
 31: };
 32: 
 33: class GraphicView: public WeatherView
 34: {
 35: public:
 36:     GraphicView(WeatherData* wd);
 37:     void Display()
 38:     {
 39:         cout << "====--Weather Report With Graphic Format--===="<< endl;
 40:         WeatherView::Display();
 41:     }
 42: };
 43: 
 44: class TableView: public WeatherView
 45: {
 46: public:
 47:     TableView(WeatherData* wd);
 48:     void Display()
 49:     {
 50:         cout << "====--Weather Report With Table Format--===="<< endl;
 51:         WeatherView::Display();
 52:     }
 53: };
 54: 
 55: #endif

===================

  1: //這個例子中WeatherData就是Subject, 而WeatherView則是Observer,
  2: //這里WeatherView中有一個包含到WeatherData的指針,
  3: //因此這里是Observer用pull的方法主動向Observer索取數據;
  4: //并且注冊和反注冊都是Observer自己執行的
  5: #include <iostream>
  6: #include <vector>
  7: #include <algorithm>
  8: #include "WeatherView.hpp"
  9: #include "WeatherData.hpp"
 10: 
 11: void WeatherData::RegisterObserver(WeatherView* obs)
 12: {
 13:     obsList.push_back(obs);
 14: }
 15: 
 16: void WeatherData::RemoveObserver(WeatherView* obs)
 17: {
 18:     vector<WeatherView*>::iterator it;
 19:     it = find(obsList.begin(), obsList.end(), obs);
 20:     if (it != obsList.end())
 21:         obsList.erase(it);
 22: }
 23: 
 24: void WeatherData::NotifyObservcer()
 25: {
 26:    vector<WeatherView*>::iterator it;
 27:    for(it = obsList.begin(); it < obsList.end(); it++)
 28:    {
 29:        (*it)->Update();
 30:    }
 31: }
 32: 
 33: 
 34: WeatherView::WeatherView(WeatherData* pwd)
 35: {
 36:     wd = pwd;
 37: }
 38: 
 39: void WeatherView::Update()
 40: {
 41:     temperature = wd->GetTemperature();
 42:     humidity = wd->GetHumidty();
 43: };
 44: 
 45: void WeatherView::Register()
 46: {
 47:     wd->RegisterObserver(this);
 48: };
 49: 
 50: void WeatherView::Unregister()
 51: {
 52:     wd->RemoveObserver(this);
 53: };
 54: 
 55: GraphicView::GraphicView(WeatherData* pwd) : WeatherView(pwd)
 56: {
 57: 
 58: }
 59: 
 60: TableView::TableView(WeatherData* pwd) : WeatherView(pwd)
 61: {
 62: 
 63: }
 64: int main()
 65: {
 66:     WeatherData *wd = new WeatherData();
 67:     GraphicView *gv = new GraphicView(wd);
 68:     gv->Register();
 69:     TableView *tv = new TableView(wd);
 70:     tv->Register();
 71: 
 72:     wd->SetWeahterData(23,45);
 73:     gv->Display();
 74:     tv->Display();
 75: 
 76:     gv->Unregister();
 77:     wd->SetWeahterData(67,89);
 78:     gv->Display();
 79:     tv->Display();
 80: 
 81:     return 0;
 82: }

======================

上面兩種實現的執行結果如下:

  1: ====--Weather Report With Graphic Format--====  
  2: temperature = 23, humidity = 45  
  3: ====--Weather Report With Table Format--====  
  4: temperature = 23, humidity = 45  
  5: ====--Weather Report With Graphic Format--====  
  6: temperature = 23, humidity = 45  
  7: ====--Weather Report With Table Format--====  
  8: temperature = 67, humidity = 89  

4. Push還是Pull?

對于上面的例子, Observer中的數據是從Subject中一次性全部更新的(temperature 和 humidity), 這種更新數據的方式便是push;然而如果WeatherData中的數據量非常大, 而有些Observer并不需要所有的數據, 比如現在要新增兩個顯示方式,一個是只顯示溫度,而另一個則只顯示濕度, 這樣的話就沒有必要讓所有的Observer都得到所有的數據. 最好的方式是Observer能根據自己的需要從Subject中去取得數據,這種更新數據的方式便是Pull. Observer模式中Push和Pull兩種設計方法體現在具體的程序中就是Observer中的Update()接口參數不同, 對于Push模式, Update()接口的參數通常就是需要Push的那些數據,比如這里的溫度和濕度; 對于Pull模式, Update()的參數是Subject的一個引用, 然后Subject提供一些數據接口,由Observer通過這些接口自己取得所需要的數據.

5. 總結:

   1. Strategy 模式定義:

      定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新.

   2. 體現的設計原則:

  • 將數據與現實分別封裝;
  • 多使用組合,少使用繼承;
  • 面向接口編程,而不面向實現編程;

   3. UML圖:

   4. 要點:

  • Strategy 基類需要定義出可供Client使用的一些算法接口;
  • 可以隨時根據需要增加 Strategy 而不會影響到Client;
  • Client 里面需要包含對 Strategy 的引用;
  • Client 可以隨時更換 Strategy;

6. 理解:

  • Observer模式是解決對象之間數據傳遞問題的一種模式;
  • Observer的注冊可以由Subject執行也可以由Observer自己執行;
  • 和Strategy模式的比較:
    1) Observer模式中Observer 中定義了 Update()接口供 Subject調用; 而Strategy模式中,Strategy定義了AlgrithmInterface()供Client調用;
    2) Observer模式中Subject和Observer是一對多的關系, 因此Subject是一次調用n個Observer的Update()接口;而Strategy模式中Client與Strategy之間是一對一的關系, Client 就是調用指定的那個Strategy的AlgrithmInterface();
    3) 也正因為這種對應關系的不同, 在Observer模式中, Subject可以Register或者Remove某個Observer, 而Strategy模式中通常只是set某個Strategy

 

原文地址: http://blog.csdn.net/zhongjiekangping/article/details/6903017


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩一区二区三区免费看| 国产日韩高清一区二区三区在线| 在线日韩中文字幕| 久久综合色一综合色88| 久久久久久久久综合| 亚洲国产三级在线| 亚洲国产精品久久久久久女王 | 亚洲影院色在线观看免费| 99国产精品久久久久老师| 国产精品美女黄网| 久久精品系列| 欧美77777| 亚洲欧美日韩精品久久亚洲区| 亚洲一区在线免费| 亚洲第一二三四五区| 亚洲激情午夜| 国产精品日本精品| 欧美xx69| 国产精品稀缺呦系列在线| 麻豆9191精品国产| 欧美日韩在线影院| 开心色5月久久精品| 欧美精品自拍偷拍动漫精品| 欧美一区二区三区啪啪| 狂野欧美一区| 欧美亚洲一区| 欧美劲爆第一页| 久久精品国产69国产精品亚洲| 嫩模写真一区二区三区三州| 亚洲免费一在线| 毛片一区二区三区| 欧美一级视频免费在线观看| 模特精品裸拍一区| 久久精品国产久精国产爱| 欧美理论电影在线播放| 久久男人资源视频| 国产精品久久久久久久电影| 欧美激情一区二区三区在线视频观看| 欧美视频日韩视频| 亚洲第一精品夜夜躁人人爽| 国产日韩亚洲| 亚洲一区在线观看视频| 99精品99| 欧美黄色一区| 欧美成人午夜剧场免费观看| 国产午夜精品久久久| 亚洲作爱视频| 一区二区三区免费看| 蜜臀91精品一区二区三区| 久久久久国产免费免费| 国产精品日韩欧美一区| 日韩系列欧美系列| 亚洲精品中文字幕在线| 久久久女女女女999久久| 欧美制服丝袜| 国产精品在线看| 亚洲一区二区三区四区在线观看 | 国产婷婷一区二区| 亚洲少妇最新在线视频| 亚洲私人影院在线观看| 欧美久久一级| 亚洲美女在线观看| 一本色道**综合亚洲精品蜜桃冫| 噜噜噜91成人网| 欧美国产在线观看| 亚洲欧洲在线免费| 欧美国产亚洲视频| 最新中文字幕亚洲| 亚洲视频在线免费观看| 欧美日韩综合久久| 亚洲一区区二区| 久久爱www.| 伊人春色精品| 免费影视亚洲| 日韩亚洲一区二区| 亚洲欧美日韩另类| 国内成+人亚洲+欧美+综合在线| 久久国产福利| 欧美mv日韩mv国产网站| 日韩亚洲国产欧美| 国产精品成人一区二区三区吃奶| 亚洲一区日本| 麻豆av福利av久久av| 亚洲黄色毛片| 欧美性大战久久久久| 亚洲欧美国产另类| 毛片av中文字幕一区二区| 亚洲日韩视频| 国产精品久久久久永久免费观看| 欧美一区二区三区四区高清| 两个人的视频www国产精品| 亚洲精品国产欧美| 国产精品美女久久久久av超清| 午夜老司机精品| 欧美激情亚洲一区| 亚洲欧美日韩综合国产aⅴ| 国产一区二区0| 欧美精品久久久久a| 亚洲一区二区三区四区在线观看| 久热精品视频在线| 亚洲视频免费在线观看| 国产日韩一区二区三区| 欧美成人激情在线| 香蕉尹人综合在线观看| 亚洲国产精品第一区二区三区| 午夜视频在线观看一区二区| 亚洲第一网站免费视频| 国产精品久久久久一区二区| 裸体女人亚洲精品一区| 亚洲永久在线| 亚洲精品中文字幕在线观看| 久久久久久久久一区二区| 一区二区三区黄色| 136国产福利精品导航网址| 国产精品国产三级国产专区53 | 亚洲性图久久| 欧美激情精品久久久久久黑人| 午夜精品视频一区| 亚洲精品你懂的| 韩国av一区二区三区| 欧美视频中文字幕在线| 欧美成人乱码一区二区三区| 欧美在线视频在线播放完整版免费观看 | 国产精品v亚洲精品v日韩精品| 久久在线免费观看| 午夜精品亚洲| 亚洲一区二区三区在线| 亚洲人线精品午夜| 欧美激情一区二区| 免费人成精品欧美精品| 久久国产精品久久w女人spa| 亚洲综合国产精品| 夜久久久久久| 日韩香蕉视频| 亚洲精品在线电影| 最近中文字幕mv在线一区二区三区四区 | 久久久91精品国产一区二区三区 | 欧美激情亚洲激情| 免费观看成人| 蜜臀99久久精品久久久久久软件| 欧美一区二区三区日韩| 欧美一二三视频| 欧美一区二区免费| 欧美一二三区在线观看| 欧美在线视频观看| 久久狠狠婷婷| 久久久久se| 免费视频亚洲| 欧美激情一区二区三区不卡| 亚洲丰满在线| 亚洲欧洲日本专区| 一区二区欧美在线| 亚洲小说春色综合另类电影| 亚洲免费在线视频| 欧美在线免费视频| 久久在线视频在线| 欧美成在线视频| 欧美视频日韩视频在线观看| 国产精品美女久久久久久2018 | 国产香蕉97碰碰久久人人| 国产亚洲精品高潮| 亚洲国产高清在线| 99精品99| 欧美在线|欧美| 久久这里只有精品视频首页| 免费试看一区| 99在线精品免费视频九九视| 亚洲与欧洲av电影| 久久免费视频在线观看| 欧美理论电影网| 国产精品自在欧美一区| 伊人精品久久久久7777| 日韩写真视频在线观看| 欧美一区二区免费| 欧美成人国产一区二区| 亚洲看片一区| 久久精品国内一区二区三区| 欧美高清视频在线播放| 国产目拍亚洲精品99久久精品| 伊人色综合久久天天| 一区二区三区 在线观看视频| 欧美一区二区三区在线视频| 欧美国产日韩一区二区三区| 中文在线不卡| 欧美 日韩 国产精品免费观看| 国产精品高潮在线| 亚洲三级电影全部在线观看高清| 亚洲欧美国产毛片在线| 亚洲成色精品| 欧美一区二区三区精品| 欧美日韩美女在线| 国产专区一区| 性感少妇一区| 99国产精品国产精品久久| 久久久综合激的五月天| 国产精品一区免费视频| 99精品国产热久久91蜜凸| 久久青草福利网站| 亚洲欧美日韩国产| 欧美四级在线|