5. 设计模式之观察者模式

天气预报项目需求,具体要求如下:

  1. 气象站可以将每天测量到的温度,温度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。
  2. 需要设计开放型API,便于其他第三方也能接入气象站获取数据
  3. 提供温度、气压和温度的接口
  4. 测量数据更新时,要能实时的通知给第三方
public class WeatherData {
    private float temperature;
    private float pressure;
    private float humidity;
    private CurrentConditions currentConditions;

    public WeatherData(CurrentConditions currentConditions) {
        this.currentConditions = currentConditions;
    }

    public void dataChange(){
        currentConditions.update(getTemperature(),getPressure(),getHumidity());
    }

    public float getTemperature(){
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public void setData(float temperature,float pressure,float humidity){
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        //调用dataChange,将最新的信息推送给接收方currentConditions
        dataChange();
    }
}
public class CurrentConditions {
    //温度、气压、水温
    private float temperature;
    private float pressure;
    private float humidity;

    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 mTemperature: " + temperature + "***");
        System.out.println("***Today mPressure: " + pressure + "***");
        System.out.println("***Today mHumidity: " + humidity + "***");
    }
}
public class Client {
    public static void main(String[] args) {
        //创建接入方currentConditions
        CurrentConditions currentConditions = new CurrentConditions();
        //创建WeatherData 并将接入方currentConditions 传递到 WeatherData中
        WeatherData weatherData = new WeatherData(currentConditions);
        //更新天气情况
        weatherData.setData(10,150,40);
        //天气情况变化
        weatherData.setData(40,160,39);
    }
}

测试:

image.png

气象站设计方案1-普通方案

问题分析

  • 其它第三方接入气象站获取数据的问题
  • 无法在运行时动态的添加第三方
  • 违反了ocp(开闭原则)原则 => 观察者模式

// 在WeartherData中,当增加一个第三方,都需要创建一个对应的第三方的公告板对象,并加入到dataChange,不利于维护,也不是动态加入。

/**
 * @program: DesignPattern
 * @description: 由观察者实现
 * @author: hmx
 * @create: 2021-06-30 21:03
 **/
public interface Observer {
    void update(float temperature,float pressure, float humidity);
}
/**
 * @program: DesignPattern
 * @description:
 * @author: hmx
 * @create: 2021-06-30 21:04
 **/
public class CurrentConditions 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 mTemperature: " + temperature + "***");
        System.out.println("***Today mPressure: " + pressure + "***");
        System.out.println("***Today mHumidity: " + humidity + "***");
    }
}
/**
 * @program: DesignPattern
 * @description:
 * @author: hmx
 * @create: 2021-06-30 21:18
 **/
public class BaiduSite 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("***baidu mTemperature: " + temperature + "***");
        System.out.println("***baidu mPressure: " + pressure + "***");
        System.out.println("***baidu mHumidity: " + humidity + "***");
    }
}
/**
 * @program: DesignPattern 让WeatherData实现
 * @description:
 * @author: hmx
 * @create: 2021-06-30 21:02
 **/
public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}
/**
 * @program: DesignPattern
 * @description:
 * 核心类:
 *     1. 包含最新的天气情况信息
 *     2. 含有观察者集合,使用ArrayList管理
 *     3. 当有数据更新时,就主动的调用 ArrayList,通知所有的(接入方)就看到最新的信息
 *
 * @author: hmx
 * @create: 2021-06-30 20:38
 **/
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 dataChange(){
        notifyObservers();
    }

    public float getTemperature(){
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public void setData(float temperature,float pressure,float humidity){
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        //调用dataChange,将最新的信息推送给接收方currentConditions
        dataChange();
    }

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

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

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this.temperature,this.pressure,this.humidity);
        }
    }
}
/**
 * @program: DesignPattern
 * @description:
 * @author: hmx
 * @create: 2021-06-30 21:13
 **/
public class Client {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();

        //创建观察者
        CurrentConditions currentConditions = new CurrentConditions();

        //注册到weatherData
        weatherData.registerObserver(currentConditions);
        weatherData.registerObserver(new BaiduSite());
        //测试
        System.out.println("通知各个注册的观察者,看看信息");
        weatherData.setData(10f,10f,10f);
    }
}

image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容