-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path观察者模式.md
110 lines (97 loc) · 4.16 KB
/
观察者模式.md
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
# 观察者模式定义
观察者模式用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。
在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。
## 观察者模式的角色
在观察者模式中有如下角色:
Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
## UML类图

## Java代码实现
定义一个接口Observer
~~~
public interface Observer {
public void update(String message);
}
~~~
定义具体观察者(ConcreteObserver)
~~~
public class QQUser implements Observer {
// 微信用户名
private String name;
public QQUser(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + "-" + message);
}
}
~~~
定义subject
~~~
public interface Subject {
/**
* 增加订阅者
* @param observer
*/
public void attach(Observer observer);
/**
* 删除订阅者
* @param observer
*/
public void detach(Observer observer);
/**
* 通知订阅者更新消息
*/
public void notify(String message);
}
~~~
定义具体的被观察者
~~~
public class SubscriptionSubject implements Subject {
//储存订阅直播的QQ用户
private List<Observer> qqUserlist = new ArrayList<Observer>();
@Override
public void attach(Observer observer) {
qqUserlist.add(observer);
}
@Override
public void detach(Observer observer) {
qqUserlist.remove(observer);
}
@Override
public void notify(String message) {
for (Observer observer : qqUserlist) {
observer.update(message);
}
}
}
~~~
客户端调用:
~~~
public class Client {
public static void main(String[] args) {
SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
//创建微信用户
QQUser user1=new QQUser("德芙");
QQUser user2=new QQUser("爱奇艺");
QQUser user3=new QQUser("腾讯");
//订阅公众号
mSubscriptionSubject.attach(user1);
mSubscriptionSubject.attach(user2);
mSubscriptionSubject.attach(user3);
//发送给所有的订阅者消息,被观察者开始发送消息
mSubscriptionSubject.notify("直播开始");
}
}
~~~
## 回调模式和观察者模式的区别
举个日常的例子,当你在android中连接网络并发送请求时,你就常常需要用到异步监听,用于监听并回调请求结果。这个就是异步回调。
观察者模式与回调模式有很多的相似处,简单对比就是:回调是一对一的关系,只监听一个事件;观察者模式则是一个主题,可以有多个监听,当主题变化时,向所有(也可以是部分)这些监听发出变化通知,观察者模式是一对多的关系。
## 编程实践(应用场景)
数据库有敏感数据被修改时候,是否可以通知敏感数据的观察者。
下载应用的时候,往往下载完成的时候,可以通知UI处理,这里也可以利用观察者模式。
当然还有很多的三方库eventbus、rxjava、rxandroid可以使用。