设计模式学习笔记四十二、观察者

一、需求

1、气象站可以将每天测量到的温度、湿度、气压等等以公告的形式发布出去(比如发布到自己的网站或者第三方)

2、需要设计开放性的PAI,便于其他第三方也能接入气象站数据

3、提供温度、气压和湿度的接口

4、测量数据更新时,要能实时的通知给第三方

二、 观察者模式介绍

1、对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject 通知Observer变化。

三、代码

package com.hao.demo.design.observer;

/**
 * @author haoxiansheng
 * @date 2020-05-26
 * @Description 让wwa
 */
public interface Subject {

    /**
     * 增加一个观察者
     * @param observer
     */
    void registerObserver(Observer observer);

    /**
     * 移除观察者
     * @param observer
     */
    void removeObserver(Observer observer);


    /**
     * 通知观察者
     */
    void notifyObserver();

}


package com.hao.demo.design.observer;

import java.util.ArrayList;

/**
 * @author
 * @date 2020-05-26
 * 1、核心类 包含最新的天气情况、观察者集合(ArrayList) 、当数据有变化时就通知观察者集合(ArrayList)去更新数据
 */
public class WeatherData implements Subject {

    // 温度、湿度、气压
    private float temperature;

    private float pressure;

    private float humidity;

    // 观察者集合
    private ArrayList<Observer> observers;

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

    // 设置数据
    public void setData(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        dataChange();
    }

    public void dataChange() {
        notifyObserver();
    }


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

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

    @Override
    public void notifyObserver() {
        observers.forEach(x -> x.update(temperature, pressure, humidity));
    }
}


package com.hao.demo.design.observer;

/**
 * @author
 * @date 2020-05-26
 */
public interface Observer {

    void update(float temperature, float pressure, float humidity);


}

package com.hao.demo.design.observer;

/**
 * @author
 * @date 2020-05-26
 */
public class CurrentConditionObserver implements Observer {
    // 温度、湿度、气压
    private float temperature;

    private float pressure;

    private float humidity;

    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }

    // 显示
    public void display() {
        System.out.println("today temperature:" + temperature);
        System.out.println("today pressure:" + pressure);
        System.out.println("today humidity" + humidity);
    }
}

package com.hao.demo.design.observer;

/**
 * @author
 * @date 2020-05-26
 */
public class BaiDuSiteObserver implements Observer {
    // 温度、湿度、气压
    private float temperature;

    private float pressure;

    private float humidity;

    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }

    // 显示
    public void display() {
        System.out.println("BaiDuSite =>today temperature:" + temperature);
        System.out.println("BaiDuSite =>today pressure:" + pressure);
        System.out.println("BaiDuSite =>today humidity" + humidity);
    }
}


package com.hao.demo.design.observer;

/**
 * @author
 * @date 2020-05-26
 */
public class Client {
    public static void main(String[] args) {
        // 创建一个WeatherData
        WeatherData weatherData = new WeatherData();
        // 创建观察者
        CurrentConditionObserver currentConditions = new CurrentConditionObserver();
        // 注册
        weatherData.registerObserver(currentConditions);
        // 测试
        weatherData.setData(12, 100, 30);
        // 新增加一个观察者
        BaiDuSiteObserver baiDuSiteObserver = new BaiDuSiteObserver();
        weatherData.registerObserver(baiDuSiteObserver);
        // 测试 数据再次变化
        weatherData.setData(13, 101, 35);
    }
}

四、观察者模式的好处

1、遵循OCP原则,新增模版不需要修改核心类

2、以集合的方式管理Observer 包括注册、移除、通知

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章