设计模式-观察者模式

来源:互联网 发布:电脑同时安装软件 编辑:程序博客网 时间:2024/06/01 09:05

借用天气观测站的例子实现观察者模式

首先需要有一个检测天气数据的 WeatherData类,此类实现了 Subject接口。Subject接口作为观察者模式中的主体,内部定义了三个方法,分别是:

    注册观察者     1. public void registerObserver(Observer observer);    移除观察者      2. public void removeObserver(Observer observer);    通知观察者更新    3. public void notifyObservers();

所有的观察者类都实现了Observer接口,此接口内部有一个update() 方法用来更新数据。

下面就要具体的Subject接口:

public class WeatherData implements Subject {    // 所有的观察者都放入这个对象中    private ArrayList observers;    // 实时监测到的气温    private float temperature;    // 湿度数据    private float humidity;    // 压强数据    private float pressure;    public WeatherData() {        observers = new ArrayList();    }    @Override    // 注册观察者即是将实现了Observer接口的对象放入观察者表中    public void registerObserver(Observer observer) {        observers.add(observer);    }    @Override    // 移除观察者即是将观察者对象移除观察者表中    public void removeObserver(Observer observer) {        int i = observers.indexOf(observer);        if (i >= 0) {            observers.remove(i);        }    }    @Override    // 将更新的数据通知给所有注册在观察者表中的对象,循环表中的每一个对象,调用其update()方法    public void notifyObservers() {        for (int i = 0; i < observers.size(); i++) {            Observer o = (Observer) observers.get(i);            o.update(temperature, humidity, pressure);        }    }    public void measurementsChanged() {        notifyObservers();    }    // 设置完数据后,通知更新    public void setMeasurements(float temp, float humidity, float pressure) {        this.temperature = temp;        this.humidity = humidity;        this.pressure = pressure;        measurementsChanged();    }}

不同的观察者需要不同的天气数据类型,但是他们都需要展示其中的数据,所以定义DisplayElement接口内部包含display() 方法。所有观察者实现 Oberver接口的同时也要实现DisplayElement接口,这样才具备展示数据的能力。

public class CustomDisplay implements Observer, DisplayElement {    // 由于此类只需要温度数据,所以只需要温度的字段    private float temperature;    @Override    public void display() {        System.out.println("Current Temperature is " + temperature + " ℃");    }    @Override    public void update(float temp, float humidity, float pressure) {        temperature = temp;        display();    }}
public class CurrentConditionsDisplay implements Observer, DisplayElement {    private float temperature;    private float humidity;    private Subject weatherData;    // 创建此观察者时,提供主体对象,实现注册    public CurrentConditionsDisplay(Subject weatherData) {        this.weatherData = weatherData;        weatherData.registerObserver(this);    }    @Override    public void display() {        System.out.println("Current Conditions: " + temperature + " ℃ " + humidity +                " % humidity");    }    @Override    public void update(float temp, float humidity, float pressure) {        this.temperature = temp;        this.humidity = humidity;        display();    }}

测试实例运行

 public static void main(String[] args) {        // 创建数据主体        WeatherData weatherData = new WeatherData();        // 创建观察者,同时完成注册        CurrentConditionsDisplay conditionsDisplay =                new CurrentConditionsDisplay(weatherData);        // 创建另一个观察者        CustomDisplay customDisplay = new CustomDisplay();        // 注册观察者        weatherData.registerObserver(customDisplay);        // 设置数据        weatherData.setMeasurements(23.5f, 79f, 30.4f);        // 移除观察者        weatherData.removeObserver(customDisplay);        weatherData.setMeasurements(30.0f, 79f, 30.4f);    }

这里写图片描述

这里写图片描述

原创粉丝点击