设计模式-观察者模式

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

首先需要有一个检测天气数据的 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);
    }

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值