观察者模式

天气预报需求

一个天气预报的项目,需求如下:

  1. 气象站可以每天测量到温度、湿度、气压等等以公告的形式发布出去
  2. 需要设计开放性API,便于第三方也能接入气象站获取数据
  3. 提供温度、气压、湿度的接口
  4. 测量数据更新时,能够实时通知给第三方

传统方案

  1. 初步设计一个WeatherData类,包含getTemperature、getHumidity、getPressure、dataUpdate四个方法
  2. 通过getXXX来获取不同信息,气象站通过调用dataUpdate来更新数据,当第三方再次获取就能得到最新数据,或者主动给第三方推送
/***
 * @author shaofan
 * @Description 传统方案解决天气预报需求
 */
public class WeatherForecast {
    public static void main(String[] args) {
        WeatherCondition weatherCondition = new WeatherCondition();
        WeatherData weatherData = new WeatherData(weatherCondition);
        weatherData.setData(1,1,1);
        System.out.println(weatherCondition);
        weatherData.setData(2,2,2);
        System.out.println(weatherCondition);
    }
}

/***
 * 第三方天气信息
 */
class WeatherCondition{
    private float temperature;
    private float pressure;
    private float humidity;

    public void update(WeatherData weatherData){
        this.temperature = weatherData.getTemperature();
        this.pressure = weatherData.getPressure();
        this.humidity = weatherData.getHumidity();
    }

    @Override
    public String toString() {
        return "WeatherCondition{" +
                "temperature=" + temperature +
                ", pressure=" + pressure +
                ", humidity=" + humidity +
                '}';
    }
}

/***
 * 气象站天气信息
 */
class WeatherData{
    private float temperature;
    private float pressure;
    private float humidity;
    private WeatherCondition weatherCondition;

    public WeatherData(WeatherCondition weatherCondition){
        this.weatherCondition = weatherCondition;
    }
    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    /**
     * 气象站更新第三方的天气
     */
    private void weatherUpdate(){
        weatherCondition.update(this);
    }

    /**
     * 气象站检测到天气更新
     * @param temperature
     * @param pressure
     * @param humidity
     */
    public void setData(float temperature,float pressure,float humidity){
        this.temperature =temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        weatherUpdate();
    }
}

问题分析

新增一个第三方,都需要创建一个新的第三方对象,并加入都dataChange中,不利于维护,也不是动态加入

观察者模式

  1. 被订阅方看作一个Subject,可以在这个Subject上面注册Observer观察者,Subject维护registerObserver、removeObserver、notifyObservers方法
  2. 观察者模式是对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化;Subject是1的一方、Observer是多的一方

观察者模式解决天气预报问题

在这里插入图片描述

/***
 * @author shaofan
 * @Description 观察者模式解决天气预报问题
 */
public class WeatherForecast {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        WeatherCondition weatherCondition = new WeatherCondition();
        weatherData.registerObserver(weatherCondition);
        weatherData.setData(1,1,1);
        System.out.println(weatherCondition);
    }
}

/***
 * 被订阅方
 */
interface Subject{
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

/***
 * 观察者
 */
interface Observer{
    void update(WeatherData weatherData);
}

class WeatherData implements Subject{
    private float temperature;
    private float pressure;
    private float humidity;
    private List<Observer> observers;
    public WeatherData(){
        observers = new ArrayList<>();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

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

    @Override
    public void removeObserver(Observer observer) {
        this.observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : this.observers) {
            observer.update(this);
        }
    }

    public void setData(float temperature,float pressure,float humidity){
        this.temperature =temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        notifyObservers();
    }
}

class WeatherCondition implements Observer{
    private float temperature;
    private float pressure;
    private float humidity;
    @Override
    public void update(WeatherData weatherData) {
        this.temperature = weatherData.getTemperature();
        this.pressure = weatherData.getPressure();
        this.humidity = weatherData.getHumidity();
    }

    @Override
    public String toString() {
        return "WeatherCondition{" +
                "temperature=" + temperature +
                ", pressure=" + pressure +
                ", humidity=" + humidity +
                '}';
    }
}

源码分析

jdk中Observeable类,使用了观察者模式
在这里插入图片描述

  1. Observable的作用等价于Subject,这里没有Subject抽象
  2. Observable已经实现了核心的方法,即管理Observer的方法
  3. Observer的地位和常规写法的Observer相同
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值