1. 程式人生 > >設計模式 - 觀察者模式

設計模式 - 觀察者模式

ray strong 分享 face 分享圖片 物理 get subject none

觀察者模式定義:

  一個目標對象管理所有相依於它的觀察者對象,並且在它本身狀態發生改變時主動發出通知

氣象檢測實例:

  如圖,氣象站是獲取實際氣象數據的物理設備,WeatherData對象是用來追蹤氣象站的數據,並更新布告板。

  擴充WeatherData對象,使得布告板能夠及時更新,並利於以後的擴展。

技術分享圖片

coding:

技術分享圖片
package Observer;

public interface Subject {

    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    
public void notifyObserver(); }
Subject

suject作為觀察目標的抽象類,其中包括註冊觀察者的抽象方法、移除已註冊的觀察者方法、通知觀察者的方法。

所有的觀察目標繼承此抽象類。

技術分享圖片
package Observer;

import java.util.ArrayList;

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 notifyObserver() { for (int i =0; i< observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
WeatherData

具體觀察目標,繼承自抽象觀察目標(subject),觀察者可調用其中的registerObserver方法動態註冊成為此觀察目標的其中一個觀察者。

notifyObserver遍歷通知所有觀察者。

技術分享圖片
package Observer;

public interface Observer {

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

觀察者抽象類,所有觀察者可繼承此類。

技術分享圖片
package Observer;

public class CurrentConditionsDisplay implements Observer {

    private float temperature;
    private float humidity;
    private float pressure;
    private Subject weatherDay;

    public CurrentConditionsDisplay(Subject subject) {
        this.weatherDay = subject;
        weatherDay.registerObserver(this);
    }

    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;

        display();
    }

    public void display() {
        System.out.println("temp = " + temperature + " humi = " + humidity + " press = " + pressure);
    }
}
CurrentConditionsDisplay

具體觀察者,在構造方法中,動態將自己註冊成某一個觀察目標的其中一個觀察者。觀察目標調用此類中的update方法動態通知數據的變化。

技術分享圖片
package com.company;

import Observer.CurrentConditionsDisplay;
import Observer.WeatherData;

public class Main {

    public static void main(String[] args) {

        WeatherData weatherData = new WeatherData();

        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);

        weatherData.setMeasurements(1, 3, 4);
    }
}
Main

run一下!

「觀察者」調用「 觀察目標」的註冊方法,將自己註冊成「觀察目標」的其中一個「觀察者」

「觀察目標」在數據變化後,調用「觀察者」的更新方法,更新「觀察者」的數據

設計模式 - 觀察者模式