设计模式-观察者模式

观察者模式,也叫发布-订阅模式

订阅的接口

1
2
3
4
5
6
package org.jit.sose.test;
public interface Subscriber {
void onSuccessEvent(UserBean userBean);
void onFailEvent(UserBean userBean);
}

接口的三个实现类,也可以叫做三个观察者或者订阅者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.jit.sose.test;
public class SubscriberImpl1 implements Subscriber {
@Override
public void onSuccessEvent(UserBean userBean) {
System.out.println("发邮件 成功, 用户信息: " + userBean);
}
@Override
public void onFailEvent(UserBean userBean) {
System.out.println("发邮件 失败, 用户信息: " + userBean);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package org.jit.sose.test;
public class SubscriberImpl2 implements Subscriber {
@Override
public void onSuccessEvent(UserBean userBean) {
System.out.println("写进本地数据库 成功, 用户信息:" + userBean);
}
@Override
public void onFailEvent(UserBean userBean) {
System.out.println("写进本地数据库 失败, 用户信息:" + userBean);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.jit.sose.test;
public class SubscriberImpl3 implements Subscriber {
@Override
public void onSuccessEvent(UserBean userBean) {
System.out.println("初始化聊天 成功, 用户信息:" + userBean);
}
@Override
public void onFailEvent(UserBean userBean) {
System.out.println("初始化聊天 失败, 用户信息:" + userBean);
}
}

用户实体类

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
package org.jit.sose.test;
public class UserBean {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "UserBean{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}

模拟登录的控制类

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
package org.jit.sose.test;
import java.util.ArrayList;
import java.util.List;
public class UserAction {
List<Subscriber> subscriberList = new ArrayList<>();
public void addSubscriber(Subscriber s){
subscriberList.add(s);
}
public void login(String name,String pass) {
if ("admin".equals(name) && "admin".equals(pass)) {
UserBean u = new UserBean();
u.setName(name);
loginSuccess(u);
} else {
UserBean u = new UserBean();
u.setName(name);
loginFail(u);
}
}
private void loginFail(UserBean userBean) {
for (Subscriber s:subscriberList) {
s.onFailEvent(userBean);
}
}
private void loginSuccess(UserBean userBean) {
for (Subscriber s:subscriberList) {
s.onSuccessEvent(userBean);
}
}
public static void main(String[] args) {
UserAction userAction = new UserAction();
userAction.addSubscriber(new SubscriberImpl1());
userAction.addSubscriber(new SubscriberImpl2());
userAction.addSubscriber(new SubscriberImpl3());
userAction.login("admin","admin");
}
}

在此例子中,用户登录成功后想要干三件事

  1. 发邮件
  2. 把自己的用户数据写进本地数据库进行缓存
  3. 初始化聊天

如果后期需求改了,登录成功之后还要做其他事,那么只要再添加一个 Subscribe 的实现类就行了,然后订阅到 UserAction 对象

登录成功之后依次调用观察者列表的 onSuccessEvent 方法, 这个过程是同步的,如果某个观察者的onSuccessEvent方法执行时出现了阻塞,将会影响其他的观察者,所以这一使用多线程的方式改进代码

改动UserAction类的loginSuccess方法如下:

1
2
3
4
5
6
7
8
9
10
private void loginSuccess(UserBean userBean) {
for (Subscriber s:subscriberList) {
new Thread(new Runnable() {
@Override
public void run() {
s.onSuccessEvent(userBean);
}
}).start();
}
}
If you think the content is useful to you.