Earth Guardian

You are not LATE!You are not EARLY!

0%

设计模式--行为型:观察者模式

观察者模式:定义一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。在主题对象在状态变化时会通知所有观察者对象,使它们自动更新

观察者模式

观察者模式 Observer Pattern:又叫发布/订阅模式 Publish/Subscribe,最常用于 GUI 系统,订阅发布系统。

类图结构

0067-Observer-uml-classdiag.png

结构解析

  • Subject
    抽象类,主题或者是抽象通知者,用于通知所有订阅了该主题的观察对象。
  • ConcreteSubject
    实现类,实现主题的具体方法。
  • Observer
    抽象类,观察者,订阅主题后,接收主题的通知并更新自己。
  • ConcreteObserver
    实现类,实现具体的更新。

示例

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
// 1. Observer
public abstract class Observer {
public abstract void update(Subject subject, Object object);
}

// 2. Subject
public abstract class Subject {
protected List<Observer> observers = new ArrayList<>();
public abstract void addObserver(Observer observer);
public abstract void deleteObserver(Observer observer);
public abstract void notify(Object object);
}

// 3. ConcreteSubject
public class ConcreteSubject extends Subject {
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}

@Override
public void deleteObserver(Observer observer) {
observers.remove(observer);
}

@Override
public void notify(Object object) {
for (Observer observer: observers){
observer.update(this, object);
}
}
}

// 4. ConcreteObserver
public class ConcreteObserver extends Observer{
@Override
public void update(Subject subject, Object object) {
System.out.println("ConcreteObserver: object = " + object);
}
}

// 5. Test
public class TestObserver {
public static void main(String[] args) {
Observer observer = new ConcreteObserver();
Subject subject = new ConcreteSubject();
subject.addObserver(observer);
subject.notify("Hello, Observer.");
}
}

// 6. Result
ConcreteObserver: object = Hello, Observer.

Java 语言规范中已经集成了标准的观察者模式 Observable/Observer,其中 Observable 即为主题或抽象通知者,Observer 为观察者。所以 Java 中实现观察者模式非常简单,主题继承 Observable ,观察者实现 Observer

总结

观察者模式很好的将观察者和主题解耦,使他们的依赖变得很小。观察者模式实现了表示层和业务逻辑层的分离,并定义了消息更新机制,符合“开闭原则”。
观察者模式实际运用中也非常常见,所有 regeister 类型都是观察者模式,如 Android.BroadcastReceiver 广播,数据库更新通知等, 以及第三方 RxJava 库等。

参考文档

  • 大话设计模式
  • Android 源码设计模式解析与实战
  • 观察者模式