ES安裝(Windows版本)
阿新 • • 發佈:2021-09-29
天氣預報專案需求
1.氣象站可以每天測量到溫度、溼度,氣壓等以公告的形式釋出出去
2.需要設計開放性API,便於其他第三方也能接入氣象站獲取資料
3.提供溫度、氣壓和溼度的介面
4.測量資料更新時,要能實時通知第三方
觀察者模式原理
觀察者模式類似訂牛奶業務
1.奶站/氣象局:Subject
2.使用者/第三方:Observer
Subject:登記註冊、移除和通知
registerObserver
註冊
removeObserver
移除
notifyObserver
通知所有註冊使用者,根據不同需求,可以是更新資料,讓使用者來取,也可以是實時推送
Observer:接收輸入
觀察者模式:物件之間多對一依賴的一種設計方案,被依賴的物件為Subject,依賴的物件為Observer,Subject通知Observer變化,比如這裡的奶站 Subject,是1的一方。使用者是Observer,是多的一方
程式碼實現
package com.cedric.observer; // 介面,讓WeatherData來實現 public interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObservers(); } package com.cedric.observer; // 觀察者介面,由觀察者實現 public interface Observer { void update(float temperature,float pressure,float humidity); }
package com.cedric.observer; public class CurrentConditions implements Observer{ // 溫度,氣壓,溼度 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(); } // 顯示 private void display() { System.out.println("Today temperature:" + temperature); System.out.println("Today pressure:" + pressure); System.out.println("Today humidity:" + humidity); } } package com.cedric.observer; public class BaiduSite implements Observer{ // 溫度,氣壓,溼度 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(); } // 顯示 private void display() { System.out.println("-------百度-----------"); System.out.println("百度~Today temperature:" + temperature); System.out.println("百度~Today pressure:" + pressure); System.out.println("百度~Today humidity:" + humidity); } }
package com.cedric.observer;
import java.util.ArrayList;
/**
* 核心
* 1.包含最新的天氣情況資訊
* 2.含有觀察者結婚,使用ArrayList管理
* 3.當資料有更新時,就主動呼叫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 float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public void dataChange(){
// 呼叫接入方的update
notifyObservers();
}
// 當資料有更新時,就呼叫setData
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) {
if(observers.contains(o)){
observers.remove(o);
}
}
// 遍歷所有的觀察者並通知
@Override
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
observers.get(i).update(this.temperature,this.pressure,this.humidity);
}
}
}
package com.cedric.observer;
public class Client {
public static void main(String[] args) {
// 建立一個Weather
WeatherData weatherData = new WeatherData();
// 建立觀察者
CurrentConditions currentConditions= new CurrentConditions();
BaiduSite baiduSite = new BaiduSite();
// 註冊到weatherData
weatherData.registerObserver(currentConditions);
weatherData.registerObserver(baiduSite);
// 測試
System.out.println("通知已註冊的觀察者");
weatherData.setData(-5,200,60);
weatherData.removeObserver(currentConditions);
System.out.println("通知已註冊的觀察者");
weatherData.setData(-5,200,60);
}
}
觀察者模式的好處
1.觀察者模式設計後,會以集合的方式來管理使用者(Observer),包括註冊、移除和通知
2.這樣我們增加觀察者,就不需要修改核心類WeatherData的程式碼,遵守了OCP原則