Java使用觀察者模式實(shí)現(xiàn)氣象局高溫預(yù)警功能示例
本文實(shí)例講述了Java使用觀察者模式實(shí)現(xiàn)氣象局高溫預(yù)警功能。分享給大家供大家參考,具體如下:
一、模式定義
觀察者模式,又稱為發(fā)布/訂閱模式。觀察者模式定義了對象間的一種一對多的依賴關(guān)系,當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對象都得到通知并被自動更新。
二、模式舉例
1 模式分析
我們借用氣象局高溫預(yù)警來說明這一模式。

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ù)警信號
*
* 標(biāo)準(zhǔn):連續(xù)三天日最高氣溫將在35℃以上。
*
* (二)高溫橙色預(yù)警信號
*
* 標(biāo)準(zhǔn):24小時(shí)內(nèi)最高氣溫將升至37℃以上。
*
* (三)高溫紅色預(yù)警信號
*
* 標(biāo)準(zhǔn):24小時(shí)內(nèi)最高氣溫將升至40℃以上。
*/
private float temperature;
// 預(yù)警級別
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ù)警級別 然后通知所有觀察者
*/
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)建主題對象
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依賴倒置原則
四、使用場合
1 當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一個(gè)方面,需要將這兩個(gè)方面分別封裝到獨(dú)立對象中,彼此獨(dú)立地改變和復(fù)用的時(shí)候。
2 當(dāng)一個(gè)系統(tǒng)中一個(gè)對象的改變需要同時(shí)改變其他對象內(nèi)容,但又不知道待改變對象到底有多少個(gè)的時(shí)候。
3 當(dāng)一個(gè)對象的改變必須通知其他對象做出相應(yīng)的變化,但是不能確定通知對象是誰的時(shí)候。
五、"推數(shù)據(jù)"靜態(tài)類圖
所謂"推數(shù)據(jù)",就是當(dāng)被觀察對象發(fā)生改變時(shí),將相關(guān)數(shù)據(jù)通過參數(shù)形式傳遞給觀察者,這就形成了被觀察者"推數(shù)據(jù)"給觀察者,靜態(tài)類圖如下:

六、"拉數(shù)據(jù)"靜態(tài)類圖
所謂"拉數(shù)據(jù)",觀察者對象含有一個(gè)對被觀察者對象實(shí)例的引用,當(dāng)被觀察者對象發(fā)生變化時(shí),不會傳遞任何數(shù)據(jù)給觀察者,而由觀察者根據(jù)被觀察者對象實(shí)例的引用主動獲取相關(guān)的數(shù)據(jù),這就形成了觀察者主動從被觀察對象中"拉數(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緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
Java數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)
下面小編就為大家?guī)硪黄狫ava數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
如何使用jenkins實(shí)現(xiàn)發(fā)布部分更新文件
這篇文章主要介紹了如何使用jenkins實(shí)現(xiàn)發(fā)布部分更新文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
一文教會你使用jmap和MAT進(jìn)行堆內(nèi)存溢出分析
本文介紹關(guān)于jmap和MAT的使用來進(jìn)行堆內(nèi)存溢出分析,因?yàn)檫@個(gè)內(nèi)存溢出是我們手動構(gòu)造出來的,查找比較簡單,真的到了生產(chǎn)上面需要我們仔細(xì)排除2021-09-09
Idea安裝及涉及springboot詳細(xì)配置的圖文教程
這篇文章主要介紹了Idea安裝及涉及springboot詳細(xì)配置,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Spring Boot從Controller層進(jìn)行單元測試的實(shí)現(xiàn)
這篇文章主要介紹了Spring Boot從Controller層進(jìn)行單元測試的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Spring Boot2發(fā)布調(diào)用REST服務(wù)實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Boot2發(fā)布調(diào)用REST服務(wù)實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

