设计模式之观察者模式

观察者模式(Observer Pattern),又叫发布-订阅模式(Publish/Subscribe Pattern),定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主题对象的状态发生变化时,会通知所有的观察者对象,使它们能够更新自己,属于行为型模式。

组成

观察者模式由抽象主题 Subject、具体主题 ConcreteSubject、抽象观察者 Observer 和具体观察者 ConcreteObserver 组成。

其中 Subject 持有一组观察者,且提供可以增加和删除观察者的接口;ConcreteSubject 实现或继承 Subject ,包含被观察的状态,状态改变时通知所有登记过的观察者;Observer 定义一个接口,收到主题通知时更新自己;ConcreteObserver 实现 Observer ,在接到通知后使自身状态与主题状态相协调。

优点

定义了稳定的消息更新传递机制,支持广播通信。

在主题和观察者之间建立一个抽象的耦合,使得可以有不同的表示层作为具体观察者角色。

缺点

主题有大量的观察者时,通知所有的观察者可能会耗时较长。

现实中很多情况下,不同的具体观察者没有实现同一个 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
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
public interface Observer {
void update();
}

public abstract class Subject {

private List<Observer> observers = new ArrayList<>();

public void attach(Observer observer) {
observers.add(observer);
}

public void detach(Observer observer) {
observers.remove(observer);
}

public void notifyObservers() {
observers.forEach(Observer::update);
}
}


public class ConcreteSubject extends Subject {

private String subjectStatus;

public String getSubjectStatus() {
return subjectStatus;
}

public void setSubjectStatus(String subjectStatus) {
this.subjectStatus = subjectStatus;
}
}

public class ConcreteObserver implements Observer {

private String name;
private ConcreteSubject subject;

private String observerStatus;

public ConcreteObserver(String name, ConcreteSubject subject) {
this.name = name;
this.subject = subject;
}

@Override
public void update() {
this.observerStatus = subject.getSubjectStatus();
System.out.println(name + " 状态随主题变化为 " + observerStatus);
}
}

public class Client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("observer1", subject);
Observer observer2 = new ConcreteObserver("observer2", subject);
subject.attach(observer1);
subject.attach(observer2);
subject.setSubjectStatus("[new status]");
subject.notifyObservers();
}
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • © 2016-2020 姜越

谢谢老板

支付宝
微信