袁艺

个人站

欢迎来到我的个人站~


观察者模式

观察者模式

定义

定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。

观察者依赖于主题,只要主题变化观察者就会被通知。

认识观察者模式

  1. 报社的业务就是出版报纸
  2. 向某家报社订阅包至,只要他们有新报纸出版,就会给你送来。只要你是他们的用户,你就会一直收到新报纸
  3. 当你不想看报纸的时候,取消订阅,他们就不会在送新报纸来
  4. 只要报社还在运营,就会一直有人向他们订阅或者取消订阅

例子:比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的界面的观察者B,B就把自己注册到A里,当A触发天气变化,就调度B的更新方法,并带上自己的上下文。

代码:

主题接口

public interface Subject {
    public void registerObserver(Observer o);
    public  void removeObserver(Observer o);
    //当主题状态改变时这个方法会被调用通知所有的观察者
    public void notifyObserver();
}

主题实现类

package ObserverParttern.ThemeAndObserver;

import java.util.ArrayList;

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temp;
    private float humidity;
    private float pressure;

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

    //当观察者注册时,将它加入list中
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    /**
     * 删除观察者
     *
     * @param o
     */
    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i > 0) {
            observers.remove(i);
        }
    }

    /**
     * 通知每个观察者更新状态
     *
     * @param o
     */
    @Override
    public void notifyObserver() {

        for (Object observer : observers) {
            Observer observer1 = (Observer) observer;
            observer1.update(temp, humidity, pressure);
        }
    }

    public void measurementChanged() {
        notifyObserver();
    }

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

}

观察者接口

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

观察者实现类

public class CurrentConditionsDisplay implements Observer, DisplayElement {
    private float temp;
    private float humidity;
    private float pressure;
    private Subject weatherData;

    public CurrentConditionsDisplay(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.humidity = humidity;
        this.pressure = pressure;
        this.temp = temp;
        display();
    }
}

测试类

    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay=new CurrentConditionsDisplay(weatherData);
        weatherData.setMeasurements(80,65,30.4f);
        weatherData.setMeasurements(82,49,33.2f);
    }

运行结果
  目前状况布告板80.0湿度65.0
  目前状况布告板82.0湿度49.0

jdk中的观察者模式

  1. Java beans
  2. swing
  3. Java.util.Observable