成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

開發(fā)之路(設(shè)計模式二:觀察者模式)

n7then / 459人閱讀

摘要:繼續(xù)我們的設(shè)計模式學(xué)習(xí),有個好的觀察者可以讓你開發(fā)效率大大提高直接進入正題,我們用一個氣象站程序來模擬此模式。內(nèi)置了觀察者模式的實現(xiàn)。

繼續(xù)我們的設(shè)計模式學(xué)習(xí),有個好的“觀察者”可以讓你開發(fā)效率大大提高

直接進入正題,我們用一個氣象站程序來模擬此模式。
有一個氣象站程序,能對濕度,溫度,氣壓進行監(jiān)測并顯示在“顯示”裝置上面
模擬圖如下,此系統(tǒng)中有三個部分
氣象站:獲取實際氣象數(shù)據(jù)的裝置
WeatherData對象:用來追蹤氣象站發(fā)出的數(shù)據(jù),并實時更新到布告欄中
布告欄:顯示目前天氣狀況給用戶看的

換個比方來說說什么是觀察者模式~~~~
1:報社的業(yè)務(wù)就是出版報紙。
2:向某家報社訂閱報紙,只要他們有新報紙出版,就會給你送來,只要你是他們的客戶,你就會一直收到新報紙。
3:當(dāng)你不想再看報紙的時候,取消訂閱,報社就不會給你送新報紙了。
4:只要報社一直存在,那么就一直會有人來訂閱或取消訂閱報紙的服務(wù)。
懂了嗎?出版社+訂閱者=觀察者模式,只不過用在“觀察者”中,出版社成為“主題”(Subject),訂閱者成為“觀察者”(Observer)

OK,讓我用視圖更好的說明

鴨子要加入了

目前只要主題那邊更新數(shù)據(jù),在觀察者這邊就都能獲得數(shù)據(jù)了。

此時狗對象不想當(dāng)觀察者了,它向“主題”提出了“離開”的意愿

狗對象離開了,當(dāng)動物(主題)對象更新數(shù)據(jù)時,狗對象是不會更新的,它已經(jīng)不是觀察者了,但同時它也可以回來重新“注冊”成觀察者。

自此觀察者模式的核心流程就是這樣了,代碼先不急著寫,先思考下。
觀察者模式定義:定義了對象之間一對多依賴,這么一來,當(dāng)一個對象改變狀態(tài)時,它的所有依賴著都會收到自動更新。

這樣的設(shè)計使得主題和多個觀察者之間的依賴性降低了,Subject只管“交互”O(jiān)bserver,至于具體怎么實現(xiàn)內(nèi)容或其他細節(jié)內(nèi)容,Subject不需要知道,它只知道指向Observer就可以了。任何時候我們都可以增加新的觀察者,因為主題唯一依賴的東西是一個實現(xiàn)Observer接口的實現(xiàn)類,即使我們隨意增加刪除觀察者都不會影響主題,我們可以獨立地復(fù)用主題或觀察者,如果我們在其他地方需要使用主題或觀察者,可以輕易復(fù)用,因為二者并非緊耦合。

設(shè)計原則一:所做的一切都是為了對象之間能松耦合。(降低依賴度)
注:松耦合的設(shè)計之所以能讓我們建立有彈性的OO系統(tǒng),能夠應(yīng)對變化,是因為對象之間的相互依賴降到最低。

主題接口

package Interface;

/**
 * 設(shè)計模式:觀察者模式 主題和觀察者之間有一對多關(guān)系
 * 
 * @author Joy
 * 
 */
// 主題接口
public interface Subject {
    // 這兩個方法都需要一個觀察者作為變量(參數(shù)設(shè)為觀察者),該觀察者是用來注冊和刪除的
    public void registerObserver(Observer o);

    public void removeObserver(Observer o);

    // 當(dāng)主題狀態(tài)改變時調(diào)用這個方法,作用是通知觀察者
    public void notifyObserver();

}

觀察者接口

package Interface;

//觀察者接口
public interface Observer {
    //當(dāng)氣象觀測數(shù)據(jù)改變時,主題會把新的狀態(tài)數(shù)據(jù)已參數(shù)形式傳遞給觀察者
    public void update(float temp, float humidity, float pressure);
}

顯示接口(顯示數(shù)據(jù))

package Interface;
public interface DisplayElement {
    public void display();
}

氣象站類(主題實現(xiàn)類)

package Implements;

import java.util.ArrayList;

import Interface.Observer;
import Interface.Subject;

//氣象站實現(xiàn)主題接口
//一個氣象站(主題)可以更新多個顯示(觀察者)面板值
public class WeatherData implements Subject {
    // 便于記錄觀察者
    private ArrayList observers;
    private float temperature;//溫度
    private float humidity;//濕度
    private float pressure;//氣壓

    public WeatherData() {
        observers = new ArrayList();
    }

    // 當(dāng)注冊觀察者時,我們只需要把它加入到ArrayList后面即可
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
        
    }
    

    // 當(dāng)觀察者想取消注冊時,從list中移除即可
    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i > 0) {
            observers.remove(i);
        }
    }

    @Override
    public void notifyObserver() {
        for (int i = 0; i < observers.size(); i++) {
            //建立觀察者對象
            Interface.Observer observer = (Interface.Observer) observers.get(i);
            //將數(shù)據(jù)更新至觀察者對象內(nèi)
            observer.update(temperature, humidity, pressure);    
            System.out.println("主題更新了數(shù)據(jù),觀察者那同步更新");
        }
    }

    // 當(dāng)從氣象站得到更新觀測值時,我們通知觀察者
    public void measurementsChanged() {
        notifyObserver();
    }

    //設(shè)置溫度,濕度,壓力值
    public void setMeasurements(float temperature, float humidity,
            float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }



    
}

下面是兩個觀察者實現(xiàn)類,氣溫濕度顯示裝置和天氣預(yù)報裝置

package Implements;

import Interface.DisplayElement;
import Interface.Observer;
import Interface.Subject;
//觀察者實現(xiàn)類
//氣溫,濕度顯示裝置
public class CurrentConditionDisplay implements Observer,DisplayElement {
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    //構(gòu)造器需要weatherData對象,用于注冊
    public CurrentConditionDisplay(Subject weatherData){
        this.weatherData=weatherData;
        //注冊
        weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        System.out.println("溫度板");
        System.out.println("溫度:"+temperature+"	"+"濕度:"+humidity);        
    }

    @Override
    public void update(float temperature, float humidity, float pressure) {
        this.temperature=temperature;
        this.humidity=humidity;
        //當(dāng)update調(diào)用時,將溫度濕度數(shù)據(jù)保存起來然后調(diào)用display
        display();        
    }
}

天氣預(yù)報類

package Implements;

import Interface.DisplayElement;
import Interface.Observer;

/**
 * 天氣預(yù)報裝置
 * 
 * @author Joy
 * 
 */
public class ForecastDisplay implements Observer, DisplayElement {
    private float currentPressure = 29.92f; // 當(dāng)前壓力值(賦個初始值)
    private float lastPressure;// 上一次壓力值
    private WeatherData weatherData;

    public ForecastDisplay(WeatherData weatherData) {
        this.weatherData = weatherData;
        // 注冊成觀察者
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        lastPressure = currentPressure;
        //pressure傳過來的壓力值
        currentPressure = pressure;
        display();
    }

    @Override
    public void display() {
        System.out.print("天氣預(yù)報: ");
        if (currentPressure > lastPressure) {
            System.out.println("天氣晴朗");
        } else if (currentPressure == lastPressure) {
            System.out.println("這次天氣狀況與上一次相同");
        } else if (currentPressure < lastPressure) {
            System.out.println("注意降溫,陰云多雨天氣");
        }
    }
}

測試類

package TestMain;



import Implements.CurrentConditionDisplay;
import Implements.ForecastDisplay;
import Implements.WeatherData;

public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        
        CurrentConditionDisplay ccd = new CurrentConditionDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
        //第一次天氣情況
        weatherData.setMeasurements(80f, 65f, 30.4f);
        System.out.println();
        //第二次天氣情況
        weatherData.setMeasurements(82f, 70f, 29.2f);
        System.out.println();
        //第三次天氣情況
        weatherData.setMeasurements(78f, 90f, 29.2f);
        
    }
}

運行效果

要點:
1:觀察者模式定義了對象之間一對多的關(guān)系。
2:主題用一個共同接口來更新觀察者。(update方法和Subject接口)
3:觀察者和可觀察者(主題)之間用松耦合的方式結(jié)合,可觀察者(主題)不知道觀察者的細節(jié),只知道觀察者實現(xiàn)了觀察者接口。
4:Java內(nèi)置了觀察者模式的實現(xiàn)。

自此完成了觀察者模式的實例,Java在JDK當(dāng)中內(nèi)置主題和觀察者的用法,這里為了更好理解,所以我寫的是自定義的形式,
這個模式理解起來并不難,但卻是個非常有用的模式,你現(xiàn)在就可以試著用觀察者和策略模式改改以前寫的舊代碼,我的感受就是隨著學(xué)習(xí)深入,就覺得以前寫的代碼很多都是有錯誤的。。。。。

感謝你看到這里,觀察者模式部分結(jié)束,本人文筆隨便,若有不足或錯誤之處望給予指點,90度彎腰~很快我會發(fā)布下一個設(shè)計模式內(nèi)容,生命不息,編程不止!

參考書籍:《Head First 設(shè)計模式》

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67612.html

相關(guān)文章

  • 設(shè)計模式(通往高手之路的必備技能)

    摘要:設(shè)計模式的定義在面向?qū)ο筌浖O(shè)計過程中針對特定問題的簡潔而優(yōu)雅的解決方案。從前由于使用的局限性,和做的應(yīng)用相對簡單,不被重視,就更談不上設(shè)計模式的問題。 ‘從大處著眼,從小處著手’,以前對這句話一知半解,自從踏出校門走入社會,開始工作以來,有了越來越深的理解,偶有發(fā)現(xiàn)這句話用在程序開發(fā)中也有用,所以,近段時間開始嘗試著分析jQuery源碼,分析angularjs源碼,學(xué)習(xí)設(shè)計模式。 設(shè)...

    paraller 評論0 收藏0
  • 開發(fā)之路設(shè)計模式三:裝飾者模式

    摘要:若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件。裝飾者類反映出被裝飾組件類型。裝飾者會導(dǎo)致設(shè)計中出現(xiàn)許多小對象,如果過度使用,會讓程序變得很復(fù)雜。 嘿嘿嘿,你是不是很喜歡用繼承呢?感覺沒什么事情是一個爸爸類搞不定的,有的話就兩個,快來跟我看看這個模式吧,它能讓你斷奶,給愛用繼承的人一個全新的設(shè)計眼界。 直奔主題,你是否有聽說...

    Vicky 評論0 收藏0
  • php設(shè)計模式

    摘要:我們今天也來做一個萬能遙控器設(shè)計模式適配器模式將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。今天要介紹的仍然是創(chuàng)建型設(shè)計模式的一種建造者模式。設(shè)計模式的理論知識固然重要,但 計算機程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進行操作,第二類是返回一個容器接口對象,上節(jié)我們介紹了...

    Dionysus_go 評論0 收藏0
  • php設(shè)計模式

    摘要:我們今天也來做一個萬能遙控器設(shè)計模式適配器模式將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。今天要介紹的仍然是創(chuàng)建型設(shè)計模式的一種建造者模式。設(shè)計模式的理論知識固然重要,但 計算機程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進行操作,第二類是返回一個容器接口對象,上節(jié)我們介紹了...

    vspiders 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<