設計模式學習筆記四十二、觀察者

一、需求

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 包括註冊、移除、通知

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