設計模式——訂閱模式(觀察者模式)

《Head First設計模式》筆記整理...歡迎交流...編程

定義

定義對象之間的一對多的依賴,這樣一來,當一個對象改變狀態時,它的全部依賴者都會收到通知並自動更新。

OO原則

  • 封裝變化
  • 多用組合,少用繼承
  • 針對接口編程,而不是針對實現編程
  • 爲了交互對象之間的鬆耦合而努力

一對多關係

圖片描述

定義類圖

圖片描述

鬆耦合的威力

鬆耦合:當兩個對象之間鬆耦合,他們依然能夠交互,可是不太清楚彼此的細節。

觀察者模式讓主題和對象之間鬆耦合。設計模式

爲何呢?測試

關於觀察者的一切,主題只知道觀察者實現看某個接口(即Observer接口)。主題不須要知道觀察值是誰,作了些什麼或其餘任何細節。this

創建一個氣象站

已知由氣象站提供WeatherData對象,用來追蹤目前的天氣情況(溫度、溼度、氣壓)。咱們須要創建三個佈告板(目前情況、氣象統計、天氣預報),分別顯示目前的情況。而且要求此應用是能夠擴展的。spa

圖片描述

public interface Subject {
    public void registerObserver(Observer o); //傳入一個觀察者變量,用來註冊觀察者
    public void registerObserver(Observer o); //傳入一個觀察者變量,用來刪除觀察者
    
    public void notifyObserver(); //當主題狀態改變時,通知觀察者

}

public interface Observer { // 全部的觀察者都必須實現update方法,以實現觀察者接口
    public void update(float temp, float humidity, float pressure); //當氣象狀態值改變時,主題會把這些狀態值當作方法的參數,傳遞給觀察者
}

public interface DisplayElement {
    public void display(); // DisplayElement接口只包含一個方法,那就是display。當不高者須要顯示時,調用此接口
}

在weatherData中實現主題接口設計

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temoerature; // 溫度
    private float humidity; // 溼度
    private float pressure; // 氣壓
    
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    
    public void removeObserver(Observer o) {
        int i = observers.indexof(o);
        if(i >= 0) {
            observers.remove(o);
        }
    }
    
    public void notifyObserver(Observer o) {
        for(int i = 0; i < observers.size(); i++) {
            Observer observer = (Observer) observers.get(i);
            observers.update(temoerature, humidity, pressure);
        }
        
    }
    
    public void measurementsChanged() {
        notifyObservers(); // 當從氣象站獲得耿勳觀測值時,咱們通知觀察者
    }
    
    public void setMeasurements(float temoerature, float humidity, float pressure) { // 這是一個測試方法
        this.temoerature = temoerature;
        this.humidity = humidity;
        this.pressure = pressure;
        this.measurementsChanged();
    }
    
    //WeatherData的其它方法
}

下面創建佈告板code

public class CurrentConditionDisplay inplements Observer, DsiplayElement {
    privete float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionDisplay(Subject weatherDate) { //構造器須要WeatherData對象
        this.weatherDate = weatherDate;
        weatherDate.registerOvserver(this);
    }
    
    public void update(temperature, humidity, weatherData) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.display();
    } 
    
    public void display() {
        System.out.print("Current conditions:" + this.temperature + "F degrees and " + this.humidity + "% humidity");
    }
}
相關文章
相關標籤/搜索