读书笔记 仅供参考
简述
观察者模式,当观察对象的状态发生变化时,会通知给观察者。适用于根据对象状态进行相应处理的场景。
角色和 UML
Subject
该角色表示观察对象,定义了注册观察者和删除观察者的方法,同时声明了获取现在状态的方法。
ConcreteSubject
具体的被观察对象,自身状态改变后,会通知已经注册的 Observer 对象。
Observer
负责接收来自 Subject 角色的状态变化的通知。
ConcreteObserver
具体的 Observer,当它的 update 方法被调用后,回去获取要观察的对象的最新状态。
UML
例子
例程是一个自动生成数字,通知观察者展示数字的程序。
public interface Observer {
//让被观察者通知观察者状态已经改变
void update(NumberGenerator generator);
}
// 以数字形式显示观察到的数值
public class DigitObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver: " + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
// 将观察到的数值以 ***** 的方式显示出来
public class GraphObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("GraphObserver: ");
int count = generator.getNumber();
for (int i = 0; i < count; i++){
System.out.print("*");
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
//作为 Subject 被观察者
public abstract class NumberGenerator {
private List<Observer> observers = new ArrayList<>();
public void addObservers(Observer observer) {
observers.add(observer);
}
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
// 向 Observer 发生通知
public void notifyObserers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer o = it.next();
o.update(this);
}
}
//获取数值
public abstract int getNumber();
//生成数值
public abstract void execute();
}
public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
@Override
public int getNumber() {
return number;
}
@Override
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
notifyObserers();
}
}
}
public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObservers(observer1);
generator.addObservers(observer2);
generator.execute();
}
}
结果
UML
要点
- 实现了可替换性,Subject 不用关注 Observer 的实现
- Observer 可能会有一定的顺序要求
- 当 Observer 对 Subject 产生影响时,注意产生循环调用
- Observer 并不是主动的去观察,而是被动的接收通知