Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

观察者模式

定义:

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。该设计模式最重要的作用就是 解耦!将观察者与被观察者解耦,使得他们之间的依赖性更小。

结构:

下图的结构是一个为上位机接收下位机状态的设计的一个类图。

ObserverRole是观察者抽象类。

AlarmLight和DetectIsStop是具体的观察者(订阅者)。

FaultStatusManager是一个具体的被观察者(发布者)。

当被观察者执行addNewStatusChange(msg)之后,被观察者将会调用notifyRoles(),通知所有List当中的对象的时候(通过执行对象中的update方法)。

1595945154834

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package javatest.pattern;

import java.util.ArrayList;
import java.util.List;

/**
* @description: 本类对观察者设计模式进行实现和测试
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:08:06
* @version: 0.0.1
*/
public class ObservationPattern {
public static void main(String[] args) {
FaultStatusPublisher faultStatusPublisher = new FaultStatusPublisher();

System.out.println("Role1 subscribe an publisher!");
BaseObserverRole role1 = new AlarmLightRole();
role1.subscribe(faultStatusPublisher);

System.out.println("Role2 subscribe an publisher!");
BaseObserverRole role2 = new DetectIsStopRole();
role2.subscribe(faultStatusPublisher);
System.out.println("\n\n\n");


System.out.println("faultStatusPublisher notify a massage!");
faultStatusPublisher.addNewStatus("alarm: new Message of :" + AlarmLightRole.class);

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n\n\n");
System.out.println("faultStatusPublisher notify another massage!");
faultStatusPublisher.addNewStatus("detect: new Message of :" + DetectIsStopRole.class);

}
}
/*
发布者、被观察者基类
*/
abstract class BasePublisher {
protected List<BaseObserverRole> observerRoles = new ArrayList<>();

/**
* 注册观察者
* @param role
*/
abstract public void attach(BaseObserverRole role);

/**
* 调用BaseObserverRoles的update,通知消息。可以考虑从队列中获取消息,实现消息同步接收发送
* @param msg
*/
abstract protected void notifyRoles(String msg);

/**
* 添加消息,调用notifyRoles方法。可以考虑队列的方式,完成消息的同步
* @param msg
*/
abstract public void addNewStatus(String msg);
}
/*
具体的发布者、被观察者
*/
class FaultStatusPublisher extends BasePublisher {
public void attach(BaseObserverRole role) {
observerRoles.add(role);
}

@Override
protected void notifyRoles(String msg) {
observerRoles.forEach((it) -> {
it.update(msg);
});
}

@Override
public void addNewStatus(String msg) {
// TODO Auto-generated method stub
notifyRoles(msg);
}
}
/*
观察者基类
*/
abstract class BaseObserverRole {
protected BasePublisher statusPublisher;

/**
* 观察者数据处理方法。
*
* @description 观察者抽象类的必要方法,通过该方法对属于自己的数据进行处理
* @author Maple Chan
* @date: 2020-07-28 22:25:46
* @params
* @return
* @param msg
*/
abstract void update(String msg);

/**
* 订阅发布者方法。
*
* @description 观察者抽象类的必要方法,通过该方法进行订阅数据
* @author Maple Chan
* @date: 2020-07-28 22:22:53
* @params statusPublisher
* @return
* @param statusPublisher
*/
abstract void subscribe(BasePublisher statusPublisher);
}

/**
* @description: 一个观察者的实现类
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:32:05
* @version: 0.0.1
*/
class AlarmLightRole extends BaseObserverRole {
private final String tag = "alarm";

@Override
public void update(String msg) {
if (msg.contains(tag)) {
System.out.println("This is AlarmLightRole message, tag is " + tag);
System.out.println("AlarmLightRole dealing message: " + msg);
}
}

@Override
void subscribe(BasePublisher faultStatusPublisher) {
this.statusPublisher = faultStatusPublisher;
faultStatusPublisher.attach(this);
}

}

/**
* @description: 一个观察者的实现类
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:32:05
* @version: 0.0.1
*/
class DetectIsStopRole extends BaseObserverRole {
private final String tag = "detect";

@Override
public void update(String msg) {
if (msg.contains(tag)) {
System.out.println("This is DetectIsStopRole message, tag is " + tag);
System.out.println("DetectIsStopRole dealing message: " + msg);
}
}

@Override
void subscribe(BasePublisher faultStatusPublisher) {
this.statusPublisher = faultStatusPublisher;
faultStatusPublisher.attach(this);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 输出:
/*
Role1 subscribe an publisher!
Role2 subscribe an publisher!




faultStatusPublisher notify a massage!
This is AlarmLightRole message, tag is alarm
AlarmLightRole dealing message: alarm: new Message of :class javatest.pattern.AlarmLightRole




faultStatusPublisher notify another massage!
This is DetectIsStopRole message, tag is detect
DetectIsStopRole dealing message: detect: new Message of :class javatest.pattern.DetectIsStopRole
*/

通过上述代码,完成了一个由一个发布者发布不同消息,不同的订阅者通过判断传入的消息进行响应的处理。该设计模式充分利用了多态的特性。BaseObserverRole引用不同的实例,在发布者调用notify的时候,将调用BaseObserverRole的update方法,该方法根据不同具体的实例,执行对应的方法。

评论