本文实例讲述了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