日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java设计模式(2 / 23):观察者模式

發布時間:2023/12/13 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java设计模式(2 / 23):观察者模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

定義

觀察者(Observer)模式定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知并自動更新。

OO設計原則:為了交互對象之間的松耦合設計而努力。

案例:氣象監測應用

概括

此系統中的三個部分是

  • 氣象站(獲取實際氣象數據的物理裝置)
  • WeatherData對象(追蹤來自氣象站的數據,并更新布告板)
  • 布告板(顯示目前天氣狀況給用戶看)
  • WeatherData對象知道如何跟物理氣象站聯系,以取得更新的數據。

    WeatherData對象會隨即更新三個布告板的顯示:

  • 目前狀況(溫度、濕度、氣壓)、
  • 氣象統計
  • 天氣預報。
  • 目標是建立一個應用,利用WeatherData對象取得數據,并更新三個布告板:目前狀況、氣象統計和天氣預報 。

    設計圖

    放碼過來

    氣象站主程序

    public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);weatherData.setMeasurements(80, 65, 30.4f);System.out.println("---");weatherData.setMeasurements(82, 70, 29.2f);System.out.println("---");weatherData.setMeasurements(78, 90, 29.2f);System.out.println("---Remove Observer---");weatherData.removeObserver(forecastDisplay);weatherData.setMeasurements(62, 90, 28.1f);} }

    布告板

    打印展現接口

    public interface DisplayElement {public void display(); }

    主題

    public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObservers(); }
    實現主題接口的氣象數據
    import java.util.*;public class WeatherData implements Subject {private List<Observer> observers;private float temperature;private float humidity;private float pressure;public WeatherData() {observers = new ArrayList<Observer>();}public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {observers.remove(o);}public void notifyObservers() {for (Observer observer : observers) {observer.update(temperature, humidity, pressure);}}public void measurementsChanged() {notifyObservers();}public void setMeasurements(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();}public float getTemperature() {return temperature;}public float getHumidity() {return humidity;}public float getPressure() {return pressure;}}

    觀察者

    public interface Observer {public void update(float temp, float humidity, float pressure); }
    實現觀察者接口的目前狀況布告板
    public class CurrentConditionsDisplay implements Observer, DisplayElement {private float temperature;private float humidity;private WeatherData weatherData;public CurrentConditionsDisplay(WeatherData weatherData) {this.weatherData = weatherData;weatherData.registerObserver(this);}public void update(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;display();}public void display() {System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");} }
    實現觀察者接口的氣象統計布告板
    public class StatisticsDisplay implements Observer, DisplayElement {private float maxTemp = 0.0f;private float minTemp = 200;private float tempSum= 0.0f;private int numReadings;private WeatherData weatherData;public StatisticsDisplay(WeatherData weatherData) {this.weatherData = weatherData;weatherData.registerObserver(this);}public void update(float temp, float humidity, float pressure) {tempSum += temp;numReadings++;if (temp > maxTemp) {maxTemp = temp;}if (temp < minTemp) {minTemp = temp;}display();}public void display() {System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)+ "/" + maxTemp + "/" + minTemp);} }
    實現觀察者接口的天氣預報布告板
    public class ForecastDisplay implements Observer, DisplayElement {private float currentPressure = 29.92f; private float lastPressure;private WeatherData weatherData;public ForecastDisplay(WeatherData weatherData) {this.weatherData = weatherData;weatherData.registerObserver(this);}public void update(float temp, float humidity, float pressure) {lastPressure = currentPressure;currentPressure = pressure;display();}public void display() {System.out.print("Forecast: ");if (currentPressure > lastPressure) {System.out.println("Improving weather on the way!");} else if (currentPressure == lastPressure) {System.out.println("More of the same");} else if (currentPressure < lastPressure) {System.out.println("Watch out for cooler, rainy weather");}} }

    運行結果

    氣象站主程序運行結果:

    Current conditions: 80.0F degrees and 65.0% humidity Avg/Max/Min temperature = 80.0/80.0/80.0 Forecast: Improving weather on the way! --- Current conditions: 82.0F degrees and 70.0% humidity Avg/Max/Min temperature = 81.0/82.0/80.0 Forecast: Watch out for cooler, rainy weather --- Current conditions: 78.0F degrees and 90.0% humidity Avg/Max/Min temperature = 80.0/82.0/78.0 Forecast: More of the same ---Remove Observer--- Current conditions: 62.0F degrees and 90.0% humidity Avg/Max/Min temperature = 75.5/82.0/62.0

    現成輪子

    Java API有內置的觀察者模式。java.util包內包含最基本的Observer接口與Observable類,這和案例的Subject接口與Observer接口很相似。

    Observer接口與Observable類使用上更方便,因為許多功能都已經事先準備好了。

    package java.util;@Deprecated(since="9") public interface Observer {void update(Observable o, Object arg); } package java.util;@Deprecated(since="9") public class Observable {private boolean changed = false;private Vector<Observer> obs;public Observable() {obs = new Vector<>();}public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}}public synchronized void deleteObserver(Observer o) {obs.removeElement(o);}public void notifyObservers() {notifyObservers(null);}public void notifyObservers(Object arg) {/** a temporary array buffer, used as a snapshot of the state of* current Observers.*/Object[] arrLocal;synchronized (this) {/* We don't want the Observer doing callbacks into* arbitrary code while holding its own Monitor.* The code where we extract each Observable from* the Vector and store the state of the Observer* needs synchronization, but notifying observers* does not (should not). The worst result of any* potential race-condition here is that:* 1) a newly-added Observer will miss a* notification in progress* 2) a recently unregistered Observer will be* wrongly notified when it doesn't care*/if (!changed)return;arrLocal = obs.toArray();clearChanged();}for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);}public synchronized void deleteObservers() {obs.removeAllElements();}protected synchronized void setChanged() {changed = true;}protected synchronized void clearChanged() {changed = false;}public synchronized boolean hasChanged() {return changed;}public synchronized int countObservers() {return obs.size();} }

    注意:Observer和Observable在Java 9標記為廢棄。

    Deprecated. This class and the Observer interface have been deprecated. The event model supported by Observer and Observable is quite limited, the order of notifications delivered by Observable is unspecified, and state changes are not in one-for-one correspondence with notifications. For a richer event model, consider using the java.beans package. For reliable and ordered messaging among threads, consider using one of the concurrent data structures in the java.util.concurrent package. For reactive streams style programming, see the java.util.concurrent.Flow API.

    Link

    參考資料

  • 《Head First 設計模式》
  • Observable (Java SE 9 & JDK 9 )
  • Java 9:Observer和Observable廢棄原因及解決方案
  • 總結

    以上是生活随笔為你收集整理的Java设计模式(2 / 23):观察者模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。