• <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>
            隨筆-167  評(píng)論-8  文章-0  trackbacks-0
            1. 解決的問(wèn)題:
               假如現(xiàn)在要編寫(xiě)一個(gè)天氣預(yù)報(bào)的公布欄, 公布欄有兩種顯示方式, 一種是圖像方式顯示, 一種是表格形式顯示.
             
            2. 問(wèn)題分析:
               應(yīng)該根據(jù)數(shù)據(jù)與現(xiàn)實(shí)分離的原則將天氣預(yù)報(bào)數(shù)據(jù)和現(xiàn)實(shí)形式分別封裝起來(lái),
               今后可能增加其他的顯示形式;
               天氣預(yù)報(bào)數(shù)據(jù)發(fā)生變化后,需要對(duì)所有的顯示形式進(jìn)行更新.
             
            3. UML圖與代碼實(shí)現(xiàn):
             1)用Push的方式更新Observer數(shù)據(jù), 通過(guò)Subject對(duì)Observer進(jìn)行注冊(cè):
             
            1. //這個(gè)例子中WeatherData就是Subject, 而WeatherView則是Observer,  
            2. //這里WeatherView中沒(méi)有包含到WeatherData的引用,  
            3. //因此這里是Subject用push的方法向Observer發(fā)送數(shù)據(jù);  
            4. //并且注冊(cè)和反注冊(cè)O(shè)bserver的時(shí)候都是由Subject(WeatherData)執(zhí)行的  
            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數(shù)據(jù), Observer自己進(jìn)行注冊(cè):
            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. //這個(gè)例子中WeatherData就是Subject, 而WeatherView則是Observer,  
            2. //這里WeatherView中有一個(gè)包含到WeatherData的指針,  
            3. //因此這里是Observer用pull的方法主動(dòng)向Observer索取數(shù)據(jù);  
            4. //并且注冊(cè)和反注冊(cè)都是Observer自己執(zhí)行的  
            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. }  
              
            上面兩種實(shí)現(xiàn)的執(zhí)行結(jié)果如下:
            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?
            對(duì)于上面的例子, Observer中的數(shù)據(jù)是從Subject中一次性全部更新的(temperature 和 humidity), 這種更新數(shù)據(jù)的方式便是push;然而如果WeatherData中的數(shù)據(jù)量非常大, 而有些Observer并不需要所有的數(shù)據(jù), 比如現(xiàn)在要新增兩個(gè)顯示方式,一個(gè)是只顯示溫度,而另一個(gè)則只顯示濕度, 這樣的話(huà)就沒(méi)有必要讓所有的Observer都得到所有的數(shù)據(jù). 最好的方式是Observer能根據(jù)自己的需要從Subject中去取得數(shù)據(jù),這種更新數(shù)據(jù)的方式便是Pull. Observer模式中Push和Pull兩種設(shè)計(jì)方法體現(xiàn)在具體的程序中就是Observer中的Update()接口參數(shù)不同, 對(duì)于Push模式, Update()接口的參數(shù)通常就是需要Push的那些數(shù)據(jù),比如這里的溫度和濕度; 對(duì)于Pull模式, Update()的參數(shù)是Subject的一個(gè)引用, 然后Subject提供一些數(shù)據(jù)接口,由Observer通過(guò)這些接口自己取得所需要的數(shù)據(jù).
             
            5. 總結(jié):
               1. Strategy 模式定義:
                  定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并被自動(dòng)更新.
             
               2. 體現(xiàn)的設(shè)計(jì)原則:
            • 將數(shù)據(jù)與現(xiàn)實(shí)分別封裝;
            • 多使用組合,少使用繼承;
            • 面向接口編程,而不面向?qū)崿F(xiàn)編程;
               3. UML圖:
             
             
               4. 要點(diǎn):
            • Strategy 基類(lèi)需要定義出可供Client使用的一些算法接口;
            • 可以隨時(shí)根據(jù)需要增加 Strategy 而不會(huì)影響到Client;
            • Client 里面需要包含對(duì) Strategy 的引用;
            • Client 可以隨時(shí)更換 Strategy;
            6. 理解:
            • Observer模式是解決對(duì)象之間數(shù)據(jù)傳遞問(wèn)題的一種模式;
            • Observer的注冊(cè)可以由Subject執(zhí)行也可以由Observer自己執(zhí)行;
            • 和Strategy模式的比較: 
              1) Observer模式中Observer 中定義了 Update()接口供 Subject調(diào)用; 而Strategy模式中,Strategy定義了AlgrithmInterface()供Client調(diào)用;
              2) Observer模式中Subject和Observer是一對(duì)多的關(guān)系, 因此Subject是一次調(diào)用n個(gè)Observer的Update()接口;而Strategy模式中Client與Strategy之間是一對(duì)一的關(guān)系, Client 就是調(diào)用指定的那個(gè)Strategy的AlgrithmInterface();
              3) 也正因?yàn)檫@種對(duì)應(yīng)關(guān)系的不同, 在Observer模式中, Subject可以Register或者Remove某個(gè)Observer, 而Strategy模式中通常只是set某個(gè)Strategy

              轉(zhuǎn)自:http://blog.csdn.net/minico/article/details/5471100
            posted on 2012-10-30 17:16 老馬驛站 閱讀(390) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Design pattern
            精品久久久无码人妻中文字幕豆芽| 久久播电影网| 日韩精品无码久久久久久| 久久亚洲AV成人无码电影| 成人久久综合网| 亚洲精品第一综合99久久| 69SEX久久精品国产麻豆| 国产精品99久久久久久宅男小说| 久久综合给久久狠狠97色| 久久精品国产亚洲AV不卡| 99久久精品国产高清一区二区| 色综合久久天天综线观看| 91久久精品91久久性色| 中文无码久久精品| 久久久久黑人强伦姧人妻| 99久久人妻无码精品系列蜜桃 | 亚洲精品无码专区久久久| 天天久久狠狠色综合| 久久久一本精品99久久精品66| 欧洲性大片xxxxx久久久| 久久er国产精品免费观看2| 久久天天躁狠狠躁夜夜网站| 久久久久久久91精品免费观看| 精品国产综合区久久久久久| 亚洲国产天堂久久综合网站| 国产亚洲精品美女久久久| 蜜臀av性久久久久蜜臀aⅴ| 久久亚洲熟女cc98cm| 亚洲伊人久久综合中文成人网 | 久久香综合精品久久伊人| 国产精品亚洲综合专区片高清久久久 | 久久人人爽人人爽人人片av高请| 伊人久久大香线蕉无码麻豆| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 亚洲欧美日韩中文久久 | 久久大香萑太香蕉av| 一本大道久久香蕉成人网| 亚洲精品无码久久千人斩| 久久99热只有频精品8| 国产精品久久自在自线观看| 亚洲国产精品人久久|