<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    每日一得

    不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速開發
    最近關心的內容:SSH,seam,flex,敏捷,TDD
    本站的官方站點是:顛覆軟件

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
    key words: 觀察者模式 Observer模式

    definition:
    defines a one-to-many dependency between objects so that when one object changes state,all of its dependents are notified and updated automatically.

    物理模型:
    觀察者注冊
    observerpattern_02.gif

    觀察者通知:
    observerpattern_03.gif
    觀察者撤銷注冊
    observerpattern_04.gif

    business: weather station
    天氣預報,在預報的數據更新后自動通知到各類不同顯示類型的終端,前提是這些終端向預報中心注冊了預定服務(register the service),這一點類似于訂閱報紙,你'訂閱'了以后就可以呆在家等郵遞員給你送過來.
    看一下類圖:weather.png


    implement:
    public?interface?Subject?{
    ????
    public?void?registerObserver(Observer?o);
    ????
    public?void?removeObserver(Observer?o);
    ????
    public?void?notifyObservers();
    }

    public?class?WeatherData?implements?Subject?{
    ????
    private?ArrayList?observers;
    ????
    private?float?temperature;
    ????
    private?float?humidity;
    ????
    private?float?pressure;
    ????
    ????
    public?WeatherData()?{
    ????????observers?
    =?new?ArrayList();
    ????}
    ????
    ????
    public?void?registerObserver(Observer?o)?{
    ????????observers.add(o);
    ????}
    ????
    ????
    public?void?removeObserver(Observer?o)?{
    ????????
    int?i?=?observers.indexOf(o);
    ????????
    if?(i?>=?0)?{
    ????????????observers.remove(i);
    ????????}
    ????}
    ????
    ????
    public?void?notifyObservers()?{
    ????????
    for?(int?i?=?0;?i?<?observers.size();?i++)?{
    ????????????Observer?observer?
    =?(Observer)observers.get(i);
    ????????????observer.update(temperature,?humidity,?pressure);
    ????????}
    ????}
    ????
    ????
    public?void?measurementsChanged()?{
    ????????notifyObservers();
    ????}
    ????
    ????
    public?void?setMeasurements(float?temperature,?float?humidity,?float?pressure)?{
    ????????
    this.temperature?=?temperature;
    ????????
    this.humidity?=?humidity;
    ????????
    this.pressure?=?pressure;
    ????????measurementsChanged();
    ????}
    ????
    ????
    //?other?WeatherData?methods?here
    ????
    ????
    public?float?getTemperature()?{
    ????????
    return?temperature;
    ????}
    ????
    ????
    public?float?getHumidity()?{
    ????????
    return?humidity;
    ????}
    ????
    ????
    public?float?getPressure()?{
    ????????
    return?pressure;
    ????}
    }

    public?interface?Observer?{
    ????
    public?void?update(float?temp,?float?humidity,?float?pressure);
    }


    public?interface?DisplayElement?{
    ????
    public?void?display();
    }

    public?class?CurrentConditionsDisplay?implements?Observer,?DisplayElement?{
    ????
    private?float?temperature;
    ????
    private?float?humidity;
    ????
    private?Subject?weatherData;
    ????
    ????
    public?CurrentConditionsDisplay(Subject?weatherData)?{
    ????????
    this.weatherData?=?weatherData;
    ????????weatherData.registerObserver(
    this);
    ????}
    ????
    ????
    public?void?update(float?temperature,?float?humidity,?float?pressure)?{
    ????????
    this.temperature?=?temperature;
    ????????
    this.humidity?=?humidity;
    ????????display();
    ????}
    ????
    ????
    public?void?display()?{
    ????????System.out.println(
    "Current?conditions:?"?+?temperature?
    ????????????
    +?"F?degrees?and?"?+?humidity?+?"%?humidity");
    ????}
    }

    public?class?WeatherStation?{

    ????
    public?static?void?main(String[]?args)?{
    ????????WeatherData?weatherData?
    =?new?WeatherData();
    ???
    ??? ??? //register to weatherData(subscribe to weatherData)
    ????????CurrentConditionsDisplay?currentDisplay?
    =new?CurrentConditionsDisplay(weatherData);
    ????????StatisticsDisplay?statisticsDisplay?
    =?new?StatisticsDisplay(weatherData);
    ????????ForecastDisplay?forecastDisplay?
    =?new?ForecastDisplay(weatherData);

    ????????weatherData.setMeasurements(
    80,?65,?30.4f);
    ????????weatherData.setMeasurements(
    82,?70,?29.2f);
    ????????weatherData.setMeasurements(
    78,?90,?29.2f);
    ????}
    }


    public?class?WeatherStationHeatIndex?{

    ????
    public?static?void?main(String[]?args)?{
    ????????WeatherData?weatherData?
    =?new?WeatherData();
    ????????CurrentConditionsDisplay?currentDisplay?
    =?new?CurrentConditionsDisplay(weatherData);
    ????????StatisticsDisplay?statisticsDisplay?
    =?new?StatisticsDisplay(weatherData);
    ????????ForecastDisplay?forecastDisplay?
    =?new?ForecastDisplay(weatherData);
    ????????HeatIndexDisplay?heatIndexDisplay?
    =?new?HeatIndexDisplay(weatherData);

    ????????weatherData.setMeasurements(
    80,?65,?30.4f);
    ????????weatherData.setMeasurements(
    82,?70,?29.2f);
    ????????weatherData.setMeasurements(
    78,?90,?29.2f);
    ????}
    }


    other places to use Observe-Pattern in JDK:

    public?class?SwingObserverExample?{
    ????JFrame?frame;
    ????
    ????
    public?static?void?main(String[]?args)?{
    ????????SwingObserverExample?example?
    =?new?SwingObserverExample();
    ????????example.go();
    ????}
    ????
    ????
    public?void?go()?{
    ????????frame?
    =?new?JFrame();

    ????????JButton?button?
    =?new?JButton("Should?I?do?it?");
    ??? ??? //register to AngelListener and DevilListener

    ????????button.addActionListener(
    new?AngelListener());
    ????????button.addActionListener(
    new?DevilListener());
    ????????frame.getContentPane().add(BorderLayout.CENTER,?button);

    ????????
    //?Set?frame?properties?
    ????????frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ????????frame.getContentPane().add(BorderLayout.CENTER,?button);
    ????????frame.setSize(
    300,300);
    ????????frame.setVisible(
    true);
    ????}
    ????
    ????
    class?AngelListener?implements?ActionListener?{
    ????????
    public?void?actionPerformed(ActionEvent?event)?{
    ????????????System.out.println(
    "Don't?do?it,?you?might?regret?it!");
    ????????}
    ????}

    ????
    class?DevilListener?implements?ActionListener?{
    ????????
    public?void?actionPerformed(ActionEvent?event)?{
    ????????????System.out.println(
    "Come?on,?do?it!");
    ????????}
    ????}
    }



    implement it with java built-in Observe-Pattern
    import?java.util.Observable;
    import?java.util.Observer;
    ????
    public?class?WeatherData?extends?Observable?{
    ????
    private?float?temperature;
    ????
    private?float?humidity;
    ????
    private?float?pressure;
    ????
    ????
    public?WeatherData()?{?}
    ????
    ????
    public?void?measurementsChanged()?{
    ????????setChanged();
    ????????notifyObservers();
    ????}
    ????
    ????
    public?void?setMeasurements(float?temperature,?float?humidity,?float?pressure)?{
    ????????
    this.temperature?=?temperature;
    ????????
    this.humidity?=?humidity;
    ????????
    this.pressure?=?pressure;
    ????????measurementsChanged();
    ????}
    ????
    ????
    public?float?getTemperature()?{
    ????????
    return?temperature;
    ????}
    ????
    ????
    public?float?getHumidity()?{
    ????????
    return?humidity;
    ????}
    ????
    ????
    public?float?getPressure()?{
    ????????
    return?pressure;
    ????}
    }






    增加一個看到的通俗版的解說:

    觀察者模式?Observer Pattern — 三國演義之超級間諜戰 — 美女貂蟬的故事

    說明:我也是初學者,希望大家能提出寶貴意見。另外轉載請注明作者左光和出處博客園,畢竟花費了很長時間才完成。

    情節:

    這一次講的故事情節很簡單,但是充滿了謀略和斗爭。大體意思就是三國初期,曹劉孫三家在徐州聯手消滅了呂布,但是自己也傷了元氣。而此時袁術得了傳國玉璽,在淮南稱帝,兵精將廣,圖謀不軌,對三家威脅都很大。于是曹劉孫三家在一起開了個會,決定派遣一名超級間諜打入到袁術身旁,監視他的一舉一動,這樣的話一旦袁術想干什么壞事,他們就可以立刻知道并做出相應的調整,知己知彼百戰百勝嘛。

    計是好計,問題是派誰去當這個超級間諜呢?正當大家愁眉苦臉的時候,美女貂蟬自告奮勇,想當年董卓那么厲害都讓 我滅了,何況一個小小的袁術呢?大家一聽,說的有理,于是就把貂蟬獻給了袁術當了妃子。另外三家還各派出一名小奸細常住在淮南城內,他們的任務是當聯絡 員,貂蟬有什么情報總不能自己曹劉孫三家挨個跑著送吧?直接丟給各國聯絡員,然后讓他們通知各自的主公就 OK 了!而三家只要一接到各自奸細的通知,就會立即做出反應。

    還有一個小插曲,袁術雖然收下了貂蟬,但是對她看管很嚴,大大方方地把情報送出去不太可能,逼不得以,貂蟬自己設計了一套密碼來傳遞情報,雖然加密 方法沒有公開,但是她想總有人可以破解了吧?沒錯,對諸葛亮來說就是小菜一碟,從此袁術穿什么內褲曹劉孫三家都知道得清清楚楚。

    分析:

    下面我們用 觀察者模式? 來分析一下上面這個故事

    1、美女貂蟬:貂蟬在觀察者模式中叫做被觀察者(Subject),主要任務是獨立的管理后臺數據和業務邏輯,同時盡可能不受前臺客戶端界面變化的影響。當然,還要負責登記或者注銷各個觀察者。

    在這個故事里,貂蟬僅僅維護了一個數據 ,就是情報 —? 私有變量 info ;另外還擁有一個業務邏輯,是用來加密 info 的方法 Reverse(string str) 。每次得到新的情報,她就會先加密,然后立刻找到在自己這登記過的聯絡員,讓這些聯絡員通知自己的主公應變。

    情報一旦發送出去, 貂蟬的任務就算完成了,具體曹劉孫三家怎么應對,是打是降還是另有其他方法,那是三家自己的事情,和她貂蟬就沒什么關系了。

    2、曹劉孫三家:曹劉孫三家在觀察者模式里叫做觀察者,主要任務就是從界面上用“各種方式”即時的反映出 被觀察者,所謂“各種方式”就是說用字符、圖形、聲音都可以表示同樣數據,外在表現不同而已,本質都是一些數據。所謂“即時”,就是說只要 被觀察者 發生變化, 觀察者 也會立刻跟著變化,用行話應該叫做刷新 Update吧。

    在這個故事里,我們可以看到運行結果中,每次貂蟬有什么新的情報,三家都會在屏幕上顯示出來,雖然很簡單,但 他們確實是用各自不同的方式表示了同樣的數據 。








    posted on 2006-08-07 20:07 Alex 閱讀(446) 評論(0)  編輯  收藏 所屬分類: design
    主站蜘蛛池模板: 亚洲精品美女久久777777| 色偷偷亚洲第一综合网| 国产成人1024精品免费| 日本三级2019在线观看免费| 亚洲欧洲美洲无码精品VA | 精品久久久久亚洲| 3d动漫精品啪啪一区二区免费 | 亚洲av午夜精品无码专区| 亚洲中文字幕无码永久在线| 亚洲午夜福利在线视频| 免费A级毛片av无码| 亚洲一区日韩高清中文字幕亚洲| 亚洲熟女综合一区二区三区| 999任你躁在线精品免费不卡| 亚洲综合精品网站| 亚洲a无码综合a国产av中文| 中文字幕无码视频手机免费看| 亚洲AV无码乱码在线观看裸奔 | 亚洲精品一卡2卡3卡四卡乱码| 69精品免费视频| 亚洲大成色www永久网站| 日韩一区二区三区免费播放| 色se01短视频永久免费| 亚洲AV人无码综合在线观看| 国产免费区在线观看十分钟| 免费看小12萝裸体视频国产 | 亚洲AV成人片无码网站| 中国在线观看免费国语版| 亚洲天堂男人天堂| 精品四虎免费观看国产高清午夜 | 亚洲一区二区三区写真 | 亚洲中文字幕无码一区二区三区 | 成全视频免费观看在线看| 国产成人精品久久亚洲| 日本特黄特色AAA大片免费| 在线观看免费亚洲| 亚洲.国产.欧美一区二区三区| 成**人免费一级毛片| 国产精品亚洲综合五月天| 免费精品国产自产拍在线观看图片| 亚洲综合色一区二区三区小说|