Java使用觀察者模式實(shí)現(xiàn)氣象局高溫預(yù)警功能示例
本文實(shí)例講述了Java使用觀察者模式實(shí)現(xiàn)氣象局高溫預(yù)警功能。分享給大家供大家參考,具體如下:
一、模式定義
觀察者模式,又稱為發(fā)布/訂閱模式。觀察者模式定義了對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。
二、模式舉例
1 模式分析
我們借用氣象局高溫預(yù)警來(lái)說(shuō)明這一模式。
2 觀察者模式靜態(tài)類圖
3 代碼示例
3.1觀察者接口一IObserver
package com.demo.observer; import com.demo.subject.ISubject; /** * 觀察者接口 * @author * */ public interface IObserver { //更新方法 public void update(ISubject subject); }
3.2主題接口一ISubject
package com.demo.subject; import com.demo.observer.IObserver; /** * 主題接口(被觀察者) * * @author * */ public interface ISubject { /** * 增加觀察者 * * @param observer * @return */ public boolean add(IObserver observer); /** * 刪除觀察者 * * @param observer * @return */ public boolean remove(IObserver observer); /** * 通知所有觀察者更新數(shù)據(jù) */ public void notifyAllObserver(); /** * 設(shè)置溫度值 * * @param temperature */ public void setTemperature(float temperature); /** * 獲得溫度預(yù)警 * * @return */ public String temperatureReport(); }
3.3具體主題實(shí)現(xiàn)一Subject
package com.demo.subject; import java.util.Iterator; import java.util.Vector; import com.demo.observer.IObserver; /** * 主題實(shí)現(xiàn)類(被觀察者) * * @author * */ public class Subject implements ISubject { // 溫度 /** * (一)高溫黃色預(yù)警信號(hào) * * 標(biāo)準(zhǔn):連續(xù)三天日最高氣溫將在35℃以上。 * * (二)高溫橙色預(yù)警信號(hào) * * 標(biāo)準(zhǔn):24小時(shí)內(nèi)最高氣溫將升至37℃以上。 * * (三)高溫紅色預(yù)警信號(hào) * * 標(biāo)準(zhǔn):24小時(shí)內(nèi)最高氣溫將升至40℃以上。 */ private float temperature; // 預(yù)警級(jí)別 private String warningLevel; // 保存觀察者列表 private final Vector<IObserver> vector; /** * 構(gòu)造方法 初始化觀察者列表 */ public Subject() { vector = new Vector<IObserver>(); } /** * 增加觀察者 */ public boolean add(IObserver observer) { if (observer != null && !vector.contains(observer)) { return vector.add(observer); } return false; } /** * 移除觀察者 */ public boolean remove(IObserver observer) { return vector.remove(observer); } /** * 通知所有觀察者更新數(shù)據(jù) */ public void notifyAllObserver() { System.out.println("======氣象部門發(fā)布高溫" + this.warningLevel + "警報(bào)!======"); Iterator<IObserver> iterator = vector.iterator(); while (iterator.hasNext()) { (iterator.next()).update(this); } } /** * 私有方法 根據(jù)溫度值設(shè)置預(yù)警級(jí)別 然后通知所有觀察者 */ private void invoke() { if (this.temperature >= 35) { if (this.temperature >= 35 && this.temperature < 37) { this.warningLevel = "黃色"; } else if (this.temperature >= 37 && this.temperature < 40) { this.warningLevel = "橙色"; } else if (this.temperature >= 40) { this.warningLevel = "紅色"; } // 通知所有觀察者溫度狀況 this.notifyAllObserver(); } } /** * 設(shè)置溫度值 * * @param temperature */ public void setTemperature(float temperature) { this.temperature = temperature; this.invoke(); } /** * 獲得溫度預(yù)警 */ public String temperatureReport() { return " 溫度:" + this.temperature; } }
3.4個(gè)人觀察者一PersonObserver
package com.demo.observer; import com.demo.subject.ISubject; /** * 個(gè)人用戶觀察者 * @author * */ public class PersonObserver implements IObserver { public void update(ISubject subject) { System.out.println("個(gè)人收到高溫預(yù)警:" + subject.temperatureReport()); } }
3.5政府觀察者一GovernmentObserver
package com.demo.observer; import com.demo.subject.ISubject; /** * 政府用戶觀察者 * @author * */ public class GovernmentObserver implements IObserver { public void update(ISubject subject) { System.out.println("政府部門收到高溫預(yù)警:" + subject.temperatureReport()); } }
3.6企事業(yè)單位觀察者一CompanyObserver
package com.demo.observer; import com.demo.subject.ISubject; /** * 企事業(yè)單位用戶觀察者 * @author * */ public class CompanyObserver implements IObserver { public void update(ISubject subject) { System.out.println("企事業(yè)單位收到高溫預(yù)警:" + subject.temperatureReport()); } }
3.7讓系統(tǒng)開始運(yùn)行一Client
package com.demo; import java.util.Random; import com.demo.observer.CompanyObserver; import com.demo.observer.GovernmentObserver; import com.demo.observer.PersonObserver; import com.demo.subject.ISubject; import com.demo.subject.Subject; /** * 客戶端應(yīng)用 * * @author * */ public class Client { /** * @param args */ public static void main(String[] args) { // 創(chuàng)建主題對(duì)象 ISubject subject = new Subject(); // 增加企事業(yè)單位觀察者 subject.add(new CompanyObserver()); // 增加政府用戶觀察者 subject.add(new GovernmentObserver()); // 增加個(gè)人用戶觀察者 subject.add(new PersonObserver()); Random random = new Random(); int i = 0; while (++i < 10) { // 設(shè)置隨機(jī)溫度 subject.setTemperature(random.nextInt(45)); } } }
4 運(yùn)行結(jié)果
======氣象部門發(fā)布高溫黃色警報(bào)!======
企事業(yè)單位收到高溫預(yù)警: 溫度:35.0
政府部門收到高溫預(yù)警: 溫度:35.0
個(gè)人收到高溫預(yù)警: 溫度:35.0
======氣象部門發(fā)布高溫紅色警報(bào)!======
企事業(yè)單位收到高溫預(yù)警: 溫度:43.0
政府部門收到高溫預(yù)警: 溫度:43.0
個(gè)人收到高溫預(yù)警: 溫度:43.0
======氣象部門發(fā)布高溫橙色警報(bào)!======
企事業(yè)單位收到高溫預(yù)警: 溫度:37.0
政府部門收到高溫預(yù)警: 溫度:37.0
個(gè)人收到高溫預(yù)警: 溫度:37.0
三、該模式設(shè)計(jì)原則
1"開——閉"原則
2單一職責(zé)原則
3依賴倒置原則
四、使用場(chǎng)合
1 當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一個(gè)方面,需要將這兩個(gè)方面分別封裝到獨(dú)立對(duì)象中,彼此獨(dú)立地改變和復(fù)用的時(shí)候。
2 當(dāng)一個(gè)系統(tǒng)中一個(gè)對(duì)象的改變需要同時(shí)改變其他對(duì)象內(nèi)容,但又不知道待改變對(duì)象到底有多少個(gè)的時(shí)候。
3 當(dāng)一個(gè)對(duì)象的改變必須通知其他對(duì)象做出相應(yīng)的變化,但是不能確定通知對(duì)象是誰(shuí)的時(shí)候。
五、"推數(shù)據(jù)"靜態(tài)類圖
所謂"推數(shù)據(jù)",就是當(dāng)被觀察對(duì)象發(fā)生改變時(shí),將相關(guān)數(shù)據(jù)通過(guò)參數(shù)形式傳遞給觀察者,這就形成了被觀察者"推數(shù)據(jù)"給觀察者,靜態(tài)類圖如下:
六、"拉數(shù)據(jù)"靜態(tài)類圖
所謂"拉數(shù)據(jù)",觀察者對(duì)象含有一個(gè)對(duì)被觀察者對(duì)象實(shí)例的引用,當(dāng)被觀察者對(duì)象發(fā)生變化時(shí),不會(huì)傳遞任何數(shù)據(jù)給觀察者,而由觀察者根據(jù)被觀察者對(duì)象實(shí)例的引用主動(dòng)獲取相關(guān)的數(shù)據(jù),這就形成了觀察者主動(dòng)從被觀察對(duì)象中"拉數(shù)據(jù)“,靜態(tài)類圖如下:
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
SpringCloud Feign如何在遠(yuǎn)程調(diào)用中傳輸文件
這篇文章主要介紹了SpringCloud Feign如何在遠(yuǎn)程調(diào)用中傳輸文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09java.lang.Instrument 代理Agent使用詳細(xì)介紹
這篇文章主要介紹了java.lang.Instrument 代理Agent使用詳細(xì)介紹的相關(guān)資料,附有實(shí)例代碼,幫助大家學(xué)習(xí)參考,需要的朋友可以參考下2016-11-11java實(shí)現(xiàn)同態(tài)加密算法的實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)同態(tài)加密算法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Spring如何更簡(jiǎn)單的讀取和存儲(chǔ)對(duì)象
這篇文章主要給大家介紹了關(guān)于Spring如何更簡(jiǎn)單的讀取和存儲(chǔ)對(duì)象的相關(guān)資料,在Spring 中想要更簡(jiǎn)單的存儲(chǔ)和讀取對(duì)象的核?是使?注解,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06SpringBoot項(xiàng)目的logback日志配置(包括打印mybatis的sql語(yǔ)句)
這篇文章主要介紹了SpringBoot項(xiàng)目的logback日志配置(包括打印mybatis的sql語(yǔ)句),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09MybatisPlus逆向工程的項(xiàng)目實(shí)踐
Mybatis-Plus逆向工程,是MP官方提供的一款代碼生成器,可以自動(dòng)生成對(duì)應(yīng)的實(shí)體類、Mapper接口和配置文件,,本文主要介紹了MybatisPlus逆向工程的項(xiàng)目實(shí)踐,感興趣的可以了解一下2024-03-03