本文實例講述了java使用觀察者模式實現氣象局高溫預警功能。分享給大家供大家參考,具體如下:
一、模式定義
觀察者模式,又稱為發布/訂閱模式。觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
二、模式舉例
1 模式分析
我們借用氣象局高溫預警來說明這一模式。
2 觀察者模式靜態類圖
3 代碼示例
3.1觀察者接口一iobserver
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.demo.observer; import com.demo.subject.isubject; /** * 觀察者接口 * @author * */ public interface iobserver { //更新方法 public void update(isubject subject); } |
3.2主題接口一isubject
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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程序設計有所幫助。
原文鏈接:https://blog.csdn.net/chengqiuming/article/details/70139427