觀察者設計模式

模式定義

觀察者設計模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時會通知全部的觀察者對象使他們可以自動更新本身。java

類圖定義

示例

氣象站的溫度,氣壓等數據變化後要推送到不一樣的統計面板。這裏的主題也就是被觀察者就是氣象站的各類數據的對象,不一樣的觀察者也就是不一樣的顯示的面板。首先定義好主題和觀察者接口,主題接口主要註冊移除和通知觀察者,觀察者接口則須要提供統一的更新本身數據的方法,在主題發生數據變化時能夠統一進行調用處理。設計模式

/**
 * 主題接口
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface Subject {

    /**
     * 註冊觀察者
     * @param o
     */
    public void registerObserver(Observer o);

    /**
     * 移除觀察者
     * @param o
     */
    public void removeObserver(Observer o);

    /**
     * 通知觀察者
     */
    public void notifyObserver();
}

/**
 * 觀察者
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface Observer {
    /**
     * 更新實時信息
     * @param temp
     * @param humidity
     * @param pressure
     */
    public void update(float temp,float humidity,float pressure);
}

/**
 * 顯示接口
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface DisplayElement {
    /**
     * 顯示方法
     */
    public void display();
}

主題和觀察者具體實現類,主題中提供數據變化方法,當數據發生變化時 ,遍歷註冊的觀察者調用觀察者的更新數據方法實現通知。ide

/**
 * 氣象數據對象(即主題)
 *
 * @author Colin
 * @create 2018-03-13
 **/
public class WeatherData implements Subject {

    private List<Observer> observers;
    private float temp;
    private float humidity;
    private float pressure;
    public WeatherData(){
        observers=new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i=observers.indexOf(o);
        if (i >= 0){
            observers.remove(o);
        }
    }

    @Override
    public void notifyObserver() {
        for (Observer observer : observers){
            observer.update(temp,humidity,pressure);
        }
    }

    public void measurementsChanged(){
        notifyObserver();
    }

    public void setMeasurements(float temp,float humidity,float pressure){
        this.temp=temp;
        this.humidity=humidity;
        this.pressure=pressure;
        notifyObserver();
    }
}

/**
 * 即時面板顯示
 *
 * @author Colin
 * @create 2018-03-13
 **/
public class CurrentConditionDisplay implements Observer,DisplayElement {

    private float temp;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionDisplay(Subject weatherData){
        this.weatherData=weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        System.out.println("當前溫度:"+temp+",當前溼度:"+humidity);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temp=temp;
        this.humidity=humidity;
    }
}

示例(java版本的觀察者模式)

java中提供Observable類做爲主題的父類,Observer 做爲觀察者接口this

/**
 * 主題
 *
 * @author Colin
 * @create 2018-03-14
 **/
public class WeatherDataJava extends Observable{

    private float temp;
    private float humdity;
    private float pressure;

    public WeatherDataJava(){}

    public void  measurementsChanged(){
        setChanged();
        notifyObservers();
    }

    public void setMeasurementsChanges(float temp,float humidity,float pressure){
        this.temp=temp;
        this.humdity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }

    public float getTemp() {
        return temp;
    }

    public void setTemp(float temp) {
        this.temp = temp;
    }

    public float getHumdity() {
        return humdity;
    }

    public void setHumdity(float humdity) {
        this.humdity = humdity;
    }

    public float getPressure() {
        return pressure;
    }

    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}
**
 * 具體觀察者
 *
 * @author Colin
 * @create 2018-03-14
 **/
public class CurrentConditionDisplayJava implements Observer ,DisplayElement{

    private Observable observer;

    private float temp;
    private float humidity;
    private float pressure;

    public CurrentConditionDisplayJava(Observable observable){
        this.observer=observable;
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof WeatherDataJava){
            WeatherDataJava weatherDataJava=(WeatherDataJava) o;
            this.temp=weatherDataJava.getTemp();
            this.humidity=weatherDataJava.getHumdity();
            this.pressure=weatherDataJava.getPressure();
            display();
        }
    }

    @Override
    public void display() {
        System.out.println("溫度:"+temp+",溼度:"+humidity+",壓力:"+pressure);
    }
}

總結

  • 觀察者模式的應用場景:當一個對象改變時須要通知到其餘對象,並且不知道有多少其餘對象的時候考慮使用。
  • 觀察者模式所作的工做其實就是在解除耦合,解除主題對象和具體觀察者之間的耦合性,當觀察者發生發生變化時不會影響的其餘的變化。設計

    涉及到的設計原則code

  • 爲交互對象之間的鬆耦合設計而努力server

相關文章
相關標籤/搜索