美文网首页Java 杂谈
HeadFirst之观察者模式

HeadFirst之观察者模式

作者: KKyKK | 来源:发表于2018-08-26 15:10 被阅读0次

观察者模式类似于报纸和杂志的订阅

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

出版者+订阅者=观察者模式

出版者成为主题(Subject),订阅者成为观察者(Observer)。

定义

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


以气象观测站为例,由WeatherDate负责追踪目前的天气状况(温度,湿度,气压),建立一个应用,有三种布告板分别显示目前的天气状,气象统计及简单的预报。
当WeatherData获得最新的数据时,三种布告板同时更新数据。

关系图

使用idea简单生成,无法再次编辑不够详细。

主题UML图
订阅UML图
public interface Subject {
    /**
     * 这两个方法都需要一个观察者对象作为参数
     * 该观察者是用来注册或者被删除的
     * @param o
     */
    void registerObserver(Observer o);

    void removeObserver(Observer o);


    /**
     * 当主题状态改变时,这个方法会被调用,以通知所有的观察者
     */
    void notifyObservers();

}
public interface Observer {

    /**
     * 所有的观察者都需要实现此方法,以实现观察者接口
     * 当主题监测的数据发送改变时,主题会把这些状态值当做方法的参数,传送给观察者
     * @param temp
     * @param humidity
     * @param pressure
     */
    void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {

    /**
     * 观察者必须实现此接口,强行使用外观显示方法
     */
    void display();
}

在WeatherData中实现主题接口

public class WeatherDate implements Subject {
    private ArrayList<Observer> observer;

    private float temoerature;
    private float humidity;
    private float ressure;

    public WeatherDate() {
        observer = new ArrayList();
    }

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

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

    /**
     * 遍历所有观察者
     * 通知他们更新数据
     */
    @Override
    public void notifyObservers() {
        for (int i = 0; i < observer.size(); i++) {
            Observer observer =  this.observer.get(i);
            observer.update(temoerature, humidity, ressure);
        }
    }

    public void measuremensChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temoerature, float humidity, float ressure) {
        this.temoerature = temoerature;
        this.humidity = humidity;
        this.ressure = ressure;
        measuremensChanged();
    }
}

定义布告栏实现Observer接口和外观显示的DisplayElement接口

只实现其中一个,其余类似

public class CurrentConditionsDisplay implements Observer, DisplayElement {

    private float temperature;
    private float humidity;
    private Subject weatherData;

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

    /**
     * 更新
     *
     * @param temp
     * @param humidity
     * @param pressure
     */
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    /**
     * 显示
     */
    @Override
    public void display() {
        System.out.println("1,当前布告板: 温度" + temperature + "度,湿度" + humidity + "%");
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        WeatherDate weatherDate = new WeatherDate();

        //注册为观察者
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherDate);
        //主题更新数据
        weatherDate.setMeasurements(20, 60, 50);
    }
}

相关文章

网友评论

    本文标题:HeadFirst之观察者模式

    本文链接:https://www.haomeiwen.com/subject/hqjoiftx.html