前言

观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

优缺点

优点

  1. 观察者和被观察者是抽象耦合的。
  2. 建立一套触发机制。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

实现

先整个被观察抽象类Observer

1
2
3
4
5
6
7
/**
* 抽象Observer类
*/
public abstract class Observer {
protected Subject subject;
public abstract void update();
}

然后整个主题类Subject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;

public int getState() {
return state;
}

public void setState(int state) {
this.state = state;
notifyAllObservers();
}

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

public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}

整三个被观察的对象继承Observer

1
2
3
4
5
6
7
8
9
10
11
public class BinaryObserver extends Observer{
public BinaryObserver(Subject subject){
this.subject=subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("BinaryObserver out: " + Integer.toBinaryString(this.subject.getState()).toUpperCase());
}
}
1
2
3
4
5
6
7
8
9
10
11
public class OctalObserver extends Observer{
public OctalObserver(Subject subject){
this.subject=subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("OctalObserver out: " + Integer.toOctalString(this.subject.getState()).toUpperCase());
}
}
1
2
3
4
5
6
7
8
9
10
11
public class HexObserver extends Observer{
public HexObserver(Subject subject){
this.subject=subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("HexaObserver out: " + Integer.toHexString(this.subject.getState()).toUpperCase());
}
}

最后可以测试下了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestObserver {
public static void main(String[] args) {
Subject subject = new Subject();

new BinaryObserver(subject);
new OctalObserver(subject);
new HexObserver(subject);

System.out.println("将state值改变成12");
subject.setState(12);
System.out.println("将state值改变成66");
subject.setState(66);
}
}

结果输出

1
2
3
4
5
6
7
8
将state值改变成12
BinaryObserver out: 1100
OctalObserver out: 14
HexaObserver out: C
将state值改变成66
BinaryObserver out: 1000010
OctalObserver out: 102
HexaObserver out: 42