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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java 设计模式之观察者模式

發(fā)布時(shí)間:2024/9/30 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 设计模式之观察者模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、了解觀察者模式

1.1 什么是觀察者模式

觀察者模式定義了對(duì)象之間的一對(duì)多依賴,這樣一來,當(dāng)一個(gè)對(duì)象狀態(tài)改變時(shí),它的所有依賴者都會(huì)收到通知并自動(dòng)更新。

典型的問題比如報(bào)社,只要你是他們的訂戶,他們每次有新報(bào)紙出版時(shí),就會(huì)向你這送來,當(dāng)你不想要看報(bào)紙時(shí),取消訂閱,他們就不會(huì)再給你送報(bào)紙。

1.2 觀察者模式組成結(jié)構(gòu)

  • 抽象主題 (Subject):抽象主題角色把所有觀察者對(duì)象保存在一個(gè)集合里,每個(gè)主題都可以有任意數(shù)量的觀察者,抽象主題提供一個(gè)接口,可以增加和刪除觀察者對(duì)象。
  • 具體主題 (ConcreteSubject):該角色將有關(guān)狀態(tài)存入具體觀察者對(duì)象,在具體主題的內(nèi)部狀態(tài)發(fā)生改變時(shí),給所有注冊(cè)過的觀察者發(fā)送通知。
  • 抽象觀察者 (Observer):是觀察者的抽象類,它定義了一個(gè)更新接口,使得在得到主題更改通知時(shí)更新自己。
  • 具體觀察者 (ConcrereObserver):實(shí)現(xiàn)抽象觀察者定義的更新接口,以便在得到主題更改通知時(shí)更新自身的狀態(tài)。

1.3 觀察者模式 UML 圖解

二、觀察者模式具體應(yīng)用

2.1 問題描述

氣象觀測(cè)站系統(tǒng):該系統(tǒng)中包含三部分,分別是氣象站 (獲取實(shí)際氣象數(shù)據(jù)的物理裝置)、WeatherData 對(duì)象 (追蹤氣象站的數(shù)據(jù),并更新布告板) 和布告板 (顯示天氣狀況給用戶看,布告板共有兩個(gè),分別顯示當(dāng)前的溫度以及對(duì)天氣進(jìn)行預(yù)告)。

2.2 問題分析

我們想要使用觀察者模式去解決這個(gè)問題,首先要分析出什么是主題,什么是觀察者,問題的關(guān)鍵是找出一對(duì)多依賴關(guān)系。這里 WeatherData 類正如所說的“一”,而“多”是用于顯示天氣情況的布告板。

WeatherData 是有狀態(tài)的對(duì)象,它包括了溫度、濕度和氣壓,而這些值都會(huì)變化,當(dāng)這些值改變時(shí),必須通知布告板,好讓它們顯示最新的數(shù)據(jù)。所以把 WeatherData 類作為主題,布告板作為觀察者。

2.3 問題分析設(shè)計(jì)圖

2.4 代碼實(shí)現(xiàn)

PS:代碼模塊較多,建議將這些代碼拷下來運(yùn)行一遍。

抽象主題接口 Subject

package com.jas.observer;public interface Subject {/*** 注冊(cè)觀察者* * @param observer 觀察者對(duì)象*/void registObserver(Observer observer);/*** 移除觀察者** @param observer 觀察者對(duì)象*/void removeObserver(Observer observer);/*** 當(dāng)主題狀態(tài)改變時(shí),這個(gè)方法會(huì)被調(diào)用,通知所有的觀察者*/void notifyObservers(); }

抽象觀察者接口 Observer

package com.jas.observer;public interface Observer {/*** 當(dāng)氣象觀測(cè)值改變時(shí),主題會(huì)把這些狀態(tài)值作為參數(shù),傳送給觀察者* * @param temp 溫度* @param humidity 濕度* @param pressure 壓力*/void update(float temp, float humidity, float pressure); }

布告信息接口 DisplayElement

package com.jas.observer;public interface DisplayElement {void display(); }

具體主題類 WeatherData

package com.jas.observer;import java.util.ArrayList; import java.util.List;public class WeatherData implements Subject {private float temperature;private float humidity;private float pressure;private List<Observer> list = new ArrayList(); //使用集合保存所有的觀察者對(duì)象@Overridepublic void registObserver(Observer observer) {list.add(observer);}@Overridepublic void removeObserver(Observer observer) {int i = list.indexOf(observer);if(i >= 0 && i < list.size()){list.remove(i);}}@Overridepublic void notifyObservers() {for (int i = 0; i < list.size(); i++) { //遍歷集合中所有觀察者對(duì)象Observer observer = list.get(i);observer.update(temperature,humidity,pressure); //調(diào)用觀察者的 update() 方法}}/*** 當(dāng)氣象站的數(shù)據(jù)得到更新后,通知觀察者,調(diào)用 notifyObservers() 方法*/public void measurementsChanged(){notifyObservers();}/*** 當(dāng)氣象站數(shù)據(jù)改變后,設(shè)置新的數(shù)據(jù)值,并調(diào)用 measurementsChanged() 方法* * @param temperature 溫度* @param humidity 濕度* @param pressure 氣壓*/public void setMeasurements(float temperature, float humidity, float pressure){this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();} }

具體觀察者對(duì)象,當(dāng)前天氣信息類 CurrentConditionsDisplay

package com.jas.observer;public class CurrentConditionsDisplay implements Observer, DisplayElement {private float temperature;private float humidity;private float pressure;private Subject weatherData;/*** 通過構(gòu)造函數(shù)將當(dāng)前觀察者注冊(cè)給具體主題對(duì)象* * @param weatherData 主題對(duì)象*/public CurrentConditionsDisplay(Subject weatherData){this.weatherData = weatherData;weatherData.registObserver(this);}/*** 布告板信息展示*/@Overridepublic void display() {System.out.println("Current conditions list : " + "溫度 = " + temperature + ", 濕度 = " + humidity + ", 氣壓 = " + pressure);}/*** 更新信息* * @param temp 溫度* @param humidity 濕度* @param pressure 壓力*/@Overridepublic void update(float temp, float humidity, float pressure) {this.temperature = temp;this.humidity = humidity;this.pressure = pressure;display();} }

具體觀察者對(duì)象,預(yù)測(cè)天氣信息類 ForecastDisplay(簡(jiǎn)單將數(shù)據(jù)減一)

package com.jas.observer;public class ForecastDisplay implements Observer, DisplayElement {private float temperature;private float humidity;private float pressure;private Subject weatherData;/*** 通過構(gòu)造函數(shù)將當(dāng)前觀察者注冊(cè)給主題對(duì)象** @param weatherData 主題對(duì)象*/public ForecastDisplay(WeatherData weatherData){this.weatherData = weatherData;weatherData.registObserver(this);}@Overridepublic void display() {System.out.println("Forecast conditions list : " + "溫度 = " +(temperature - 1.0) + ", 濕度 = " + (humidity - 1.0) + ", 氣壓 = " + (pressure - 1.0));}@Overridepublic void update(float temp, float humidity, float pressure) {this.temperature = temp;this.humidity = humidity;this.pressure = pressure;display();} }

氣象站類 WeatherStation

package com.jas.observer;public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);//當(dāng)具體主題對(duì)象數(shù)據(jù)發(fā)生變化,所有依賴者 (觀察者) 都會(huì)實(shí)現(xiàn)自動(dòng)數(shù)據(jù)更新weatherData.setMeasurements(18,65,30);} }/*** 輸出* Current conditions list : 溫度 = 18.0, 濕度 = 65.0, 氣壓 = 30.0* Forecast conditions list : 溫度 = 17.0, 濕度 = 64.0, 氣壓 = 29.0*/

2.5 自定義觀察者模式總結(jié)

觀察者模式可以輕松實(shí)現(xiàn)松耦合,因?yàn)橹黝}并不需要知道觀察者的具體類是誰,做了些什么,并且我們可以在任何時(shí)候新增觀察者。由于一個(gè)主題可能對(duì)應(yīng)多個(gè)觀察者,所以當(dāng)某一個(gè)觀察者出現(xiàn)問題時(shí),可能導(dǎo)致其他的觀察者也不能正常工作。因此在一定程度上,存在著效率問題。

三、Java 內(nèi)置觀察者模式

3.1 了解 Java 內(nèi)置觀察者模式

java.util 包內(nèi) 包含最基本的Observable 類與 Observer 接口,這和上面的 Subject 接口與 Observer 接口很類似。Observable 類與 Observer 接口使用起來更方便,因?yàn)樵S多的功能已經(jīng)提供了。

3.2 Java 內(nèi)置觀察者模式如何運(yùn)作

(1)如何把對(duì)象定義為觀察者?

實(shí)現(xiàn)觀察者 (Observer) 接口,調(diào)用任何 Observable 對(duì)象的 addObserve() 方法。當(dāng)不想要當(dāng)觀察者時(shí),調(diào)用 deleteObserve() 方法。

(2)可觀察者如何發(fā)送通知?

  • 先調(diào)用 setChanged() 方法,標(biāo)記狀態(tài)已經(jīng)被改變的事實(shí)。
  • 調(diào)用 notifyObservers() 或 notifyObservers(Object arg) 方法。
  • (3)觀察者如何接收通知?

    同以前一樣,觀察者實(shí)現(xiàn)了 update(Observable o, Object arg) 方法,只是方法簽名不太一樣。

    3.3 重寫氣象觀測(cè)站系統(tǒng)

    主題類 WeatherData

    package com.jas.jdk.observer;import java.util.Observable;public class WeatherData extends Observable {private float temperature;private float humidity;private float pressure;public void measurementsChanged(){//在通知所有觀察者之前,先調(diào)用 setChanged() 方法,用來表示狀態(tài)已經(jīng)改變setChanged();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;} }

    具體觀察者對(duì)象,當(dāng)前天氣信息類 CurrentConditionsDisplay

    package com.jas.jdk.observer;import java.util.Observable; import java.util.Observer;public class CurrentConditionsDisplay implements Observer, DisplayElement {private float temperature;private float humidity;private float pressure;private Observable observable;/*** 通過構(gòu)造函數(shù),將當(dāng)前對(duì)象記錄為觀察者* * @param observable 主題對(duì)象*/public CurrentConditionsDisplay(Observable observable){this.observable = observable;observable.addObserver(this);}@Overridepublic void display() {System.out.println("Current conditions list : " + "溫度 = " +temperature + ", 濕度 = " + humidity + ", 氣壓 = " + pressure);}@Overridepublic void update(Observable o, Object arg) {if(o instanceof WeatherData){WeatherData weatherData = (WeatherData) o;this.temperature = weatherData.getTemperature();this.humidity = weatherData.getHumidity();this.pressure = weatherData.getPressure();display();}} }

    氣象站類 WeatherStation(同上)

    package com.jas.jdk.observer;public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);//ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);weatherData.setMeasurements(80,65,30.4f);} }/*** 輸出* Current conditions list : 溫度 = 80.0, 濕度 = 65.0, 氣壓 = 30.4*/

    3.4 Java 內(nèi)置觀察者模式總結(jié)

    Java 內(nèi)置的觀察者模式允許觀察者有選擇的獲取數(shù)據(jù),而不是主題對(duì)象強(qiáng)制將更新數(shù)據(jù)全部推送個(gè)每個(gè)觀察者。

    Observable 是一個(gè)類,并不是一個(gè)接口,這意味著你繼承它的同時(shí),不能再繼承其他的類。在 Observable 類中 setChanged() 方法被保護(hù)了起來 (protected),除非你繼承該類,否則你無法創(chuàng)建 Observable 實(shí)例組合到你自己的對(duì)象中來。所以它違反了一個(gè)原則:“多用組合,少用繼承”。

    還有一點(diǎn)需要要注意的是:內(nèi)置的觀察者模式,觀察者被通知的順序并不是唯一的 (上面只定義了一個(gè)觀察者),有時(shí)候并不能達(dá)到我們一開始的目的,你可以定義多個(gè)觀察者驗(yàn)證一下。

    根據(jù)具體的需求,如果 Java 內(nèi)置的觀察者模式 API 不能滿設(shè)計(jì),那么我們可以像剛開始那樣自己實(shí)現(xiàn)一套觀察者模式。

    PS:點(diǎn)擊了解更多設(shè)計(jì)模式 http://blog.csdn.net/codejas/article/details/79236013

    參考文獻(xiàn)

    《Head First 設(shè)計(jì)模式》

    總結(jié)

    以上是生活随笔為你收集整理的Java 设计模式之观察者模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 香蕉久久国产 | 99热在线只有精品 | 日日夜夜天天干 | 亚洲成人免费视频 | 美女脱光衣服让男人捅 | 国产精品久久久精品三级 | 欧美日韩大陆 | 色屁屁ts人妖系列二区 | 手机免费看av片 | 涩涩视频在线观看 | 免费福利影院 | 天堂久久精品 | 国产无码精品久久久 | 五月视频| 天堂在线观看 | 色诱av手机版 | 中国丰满熟妇xxxx性 | 台湾综合色 | 国产美女av在线 | 婷婷婷色| 日本不卡视频一区二区三区 | 亚洲成人免费电影 | 免费网站观看www在线观 | 亚洲成人av影片 | 综合国产精品 | 韩日精品在线 | 午夜av一区 | 国产男男gay体育生网站 | 一本色道久久综合亚洲二区三区 | 日韩毛片免费看 | 高清免费av| 欧美一级不卡 | 欧美成人性生活视频 | 亚洲AV无码成人精品区麻豆 | 日韩久久综合 | 少妇欧美激情一区二区三区 | 欧美性插视频 | 夜夜cao | 亚洲图片 欧美 | 国产精品.com | 成人性生交大片免费看中文 | 日日舔夜夜操 | 色999日韩 | 国产三级在线播放 | 97国产精东麻豆人妻电影 | 日本热久久 | 日韩一二三级 | 视频一区三区 | 亚洲成人久久久久 | 精品国产aⅴ麻豆 | 不卡av免费在线观看 | 亚洲色图清纯唯美 | 艳妇乳肉豪妇荡乳av无码福利 | 国产精品18久久久久久vr下载 | 国产黄色片免费观看 | 伊人久久超碰 | 国产精品1234 | 成人福利网站在线观看 | 91精品国产免费 | 日韩一区二区三区免费 | 日日夜夜天天干 | 国产一区啪啪 | 国产色诱视频 | 黄色裸体视频 | 欧美xxxx日本和非洲 | 激情综合五月 | 国产又大又粗又长 | 九九综合九九综合 | 日韩在线视频免费看 | 丝袜 中出 制服 人妻 美腿 | 天堂av2019| 亚洲大片| 日本a级黄 | 欧美中文日韩 | 黄色三级三级三级 | 黄色片不卡| 在线欧美日韩国产 | 九九精品视频在线观看 | 欧美乱码精品一区二区三区 | 婷婷深爱五月 | 欧洲国产精品 | 久草免费福利视频 | 黄色美女毛片 | 欧美一级片观看 | 波多野结衣中文字幕在线 | 亚洲aa在线观看 | 日韩美女av在线 | 99国产揄拍国产精品 | 人人草人人爱 | 色女孩综合| 一级片网址 | 香港三级日本三级三69 | 91爱爱视频 | 男生吃小头头的视频 | 91亚洲精品一区二区乱码 | www.久久艹 | 一区二区三区四区国产精品 | 亚洲av无码日韩精品影片 | 内射一区二区 |