本文實例講述了Java使用觀察者模式實現氣象局高溫預警功能。分享給大家供大家參考,具體如下:
一、模式定義
觀察者模式,又稱為發布/訂閱模式。觀察者模式定義了對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對像都得到通知並被自動更新。
二、模式舉例
1 模式分析
我們藉用氣象局高溫預警來說明這一模式。
2 觀察者模式靜態類圖
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); /** * 通知所有觀察者更新數據*/ public void notifyAllObserver(); /** * 設置溫度值* * @param temperature */ public void setTemperature(float temperature); /** * 獲得溫度預警* * @return */ public String temperatureReport();}3.3具體主題實現一Subject
package com.demo.subject;import java.util.Iterator;import java.util.Vector;import com.demo.observer.IObserver;/** * 主題實現類(被觀察者) * * @author * */public class Subject implements ISubject { // 溫度/** * (一)高溫黃色預警信號* * 標準:連續三天日最高氣溫將在35℃以上。 * * (二)高溫橙色預警信號* * 標準:24小時內最高氣溫將升至37℃以上。 * * (三)高溫紅色預警信號* * 標準:24小時內最高氣溫將升至40℃以上。 */ private float temperature; // 預警級別private String warningLevel; // 保存觀察者列表private final Vector<IObserver> vector; /** * 構造方法初始化觀察者列表*/ 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); } /** * 通知所有觀察者更新數據*/ public void notifyAllObserver() { System.out.println("======氣象部門發布高溫" + this.warningLevel + "警報!======"); Iterator<IObserver> iterator = vector.iterator(); while (iterator.hasNext()) { (iterator.next()).update(this); } } /** * 私有方法根據溫度值設置預警級別然後通知所有觀察者*/ 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(); } } /** * 設置溫度值* * @param temperature */ public void setTemperature(float temperature) { this.temperature = temperature; this.invoke(); } /** * 獲得溫度預警*/ public String temperatureReport() { return " 溫度:" + this.temperature; }}3.4個人觀察者一PersonObserver
package com.demo.observer;import com.demo.subject.ISubject;/** * 個人用戶觀察者* @author * */public class PersonObserver implements IObserver{ public void update(ISubject subject) { System.out.println("個人收到高溫預警:" + 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("政府部門收到高溫預警:" + subject.temperatureReport()); }}3.6企事業單位觀察者一CompanyObserver
package com.demo.observer;import com.demo.subject.ISubject;/** * 企事業單位用戶觀察者* @author * */public class CompanyObserver implements IObserver{ public void update(ISubject subject) { System.out.println("企事業單位收到高溫預警:" + subject.temperatureReport()); }}3.7讓系統開始運行一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;/** * 客戶端應用* * @author * */public class Client { /** * @param args */ public static void main(String[] args) { // 創建主題對象ISubject subject = new Subject(); // 增加企事業單位觀察者subject.add(new CompanyObserver()); // 增加政府用戶觀察者subject.add(new GovernmentObserver()); // 增加個人用戶觀察者subject.add(new PersonObserver()); Random random = new Random(); int i = 0; while (++i < 10) { // 設置隨機溫度subject.setTemperature(random.nextInt(45)); } }}4 運行結果
======氣象部門發布高溫黃色警報!======
企事業單位收到高溫預警: 溫度:35.0
政府部門收到高溫預警: 溫度:35.0
個人收到高溫預警: 溫度:35.0
======氣象部門發布高溫紅色警報!======
企事業單位收到高溫預警: 溫度:43.0
政府部門收到高溫預警: 溫度:43.0
個人收到高溫預警: 溫度:43.0
======氣象部門發布高溫橙色警報!======
企事業單位收到高溫預警: 溫度:37.0
政府部門收到高溫預警: 溫度:37.0
個人收到高溫預警: 溫度:37.0
三、該模式設計原則
1"開――閉"原則
2單一職責原則
3依賴倒置原則
四、使用場合
1 當一個抽像模型有兩個方面,其中一個方面依賴於另一個方面,需要將這兩個方面分別封裝到獨立對像中,彼此獨立地改變和復用的時候。
2 當一個系統中一個對象的改變需要同時改變其他對象內容,但又不知道待改變對像到底有多少個的時候。
3 當一個對象的改變必須通知其他對像做出相應的變化,但是不能確定通知對像是誰的時候。
五、"推數據"靜態類圖
所謂"推數據",就是當被觀察對象發生改變時,將相關數據通過參數形式傳遞給觀察者,這就形成了被觀察者"推數據"給觀察者,靜態類圖如下:
六、"拉數據"靜態類圖
所謂"拉數據",觀察者對象含有一個對被觀察者對象實例的引用,當被觀察者對象發生變化時,不會傳遞任何數據給觀察者,而由觀察者根據被觀察者對象實例的引用主動獲取相關的數據,這就形成了觀察者主動從被觀察對像中"拉數據“,靜態類圖如下:
更多java相關內容感興趣的讀者可查看本站專題:《Java面向對象程序設計入門與進階教程》、《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。