长大后想做什么?做回小孩!

0%

观察者模式

观察者模式(ObserverPattern)是一种行为型模式,它提供了一种定义对象之间一对多关系的方式。

顾名思义,观察者模式自然是需要有一些观察者(Observer)去”观察”被观察者(Subject)的行为,同时被观察者的状态(status)随时有可能发生改变,当这种改变发生的时候,被观察者需要去”通知”所有正在”观察自己”的观察者们。

观察者和被观察者之间的这种关系也可以叫做”订阅——发布”,所以观察者模式又叫做发布订阅模式。

正文

有一个博客平台(Subject)定期会推送文章,已经订阅过得QQ或者WeChat用户(Observer)。这就构成了一个简单的观察者模式的应用场景。

被观察者:

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
public abstract class Blog {
//关注列表,维护一对多的关系
private final List<User> users = new ArrayList<>();
//关注
public Blog subscribe(User user) {
users.add(user);
return this;
}
//取关
public void unsubscribe(User user) {
users.remove(user);
}
//有文章更新,通知关注列表里的人
public void notifyUsers() {
users.forEach(User::update);
}
}

public class MyBlog extends Blog {
public void doSomethings() {
//业务代码。。。
//通知关注用户
super.notifyUsers();
}
}

观察者:

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
public interface User {
//接收被观察者的通知消息
void update();
}

public class QQUser implements User {
private String QQName;

public QQUser(String QQName) {
this.QQName = QQName;
}

@Override
public void update() {
System.out.println("QQ用户"+ QQName +"收到提醒!");
}
}

public class WeChatUser implements User {
private String WeChatName;

public WeChatUser(String weChatName) {
WeChatName = weChatName;
}

@Override
public void update() {
System.out.println("WeChat用户"+ WeChatName +"收到提醒!");
}
}

验证:

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
MyBlog myBlog = new MyBlog();
myBlog.subscribe(new QQUser("煎饼果子"))
.subscribe(new WeChatUser("aa"))
.subscribe(new QQUser("韭菜盒子"));
myBlog.doSomethings();
}
//QQ用户煎饼果子收到提醒!
//WeChat用户aa收到提醒!
//QQ用户韭菜盒子收到提醒!

类图:

w7wZjJ.png

在 JDK 中也提供了对观察者模式的支持,被观察者可以继承父类 java.util.Observable ,观察者可以实现 java.util.Observable 接口。

w7wE3F.png

优点:被观察者和观察者是抽象耦合的,该模式建立了一套触发机制。

缺点:如果被观察者有很多直接或间接的观察者时,通知每一个观察者会很花费时间。如果观察者和被观察者有循环依赖调用的时候可能会导致系统崩溃。没有一个机制让观察者直到被观察者是怎么发生变化的,仅仅知道目标发生了变化。


菜鸟本菜,不吝赐教,感激不尽!

更多题解源码和学习笔记:githubCSDNM1ng