目录
1.Observer模式
1.1 作用
在观察者模式中,当被观察对象的状态发生变化时,会通知给观察者。适用于根据对象状态进行相应处理的场景。
1.2 示例程序
1.2.1 示例程序类图
1.2.2 Observer接口
public interface Observer {
public abstract void update(NumberGenerator generator);//接口根据被观察者的状态更新
}
1.2.3 NumberGenarator抽象类
//被观察者,生成数值的抽象类
public abstract class NumberGenerator {
private List<Observer> observers = new ArrayList<>();//观察者集合
public void addObserver(Observer observer) {//注册观察者
observers.add(observer);
}
public void deleteobserver(Observer observer) {//删除观察者
observers.remove(observer);
}
public void notifyObservers() {//通知每个观察者进行更新
Iterator it = observers.listIterator();
while (it.hasNext()) {
Observer o = (Observer) it.next();
o.update(this);
}
}
public abstract int getNumber();//获取数值
public abstract void execute();//生成数值
}
1.2.4 RandomNumberGenerator类
//具体的被观察者
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 < 5;i++) {
//产生新的数值后通知所有观察者
number = random.nextInt(5);
notifyObservers();
}
}
}
1.2.5 具体的观察者类
//具体的观察者
public class DigitObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try{
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//具体的观察者
public class GraphObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
System.out.print("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) {
e.printStackTrace();
}
}
}
1.2.6 Main类
public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();//被观察者改变状态
}
}
输出:
1.3 Observer模式中的角色
- Subject(观察对象):该角色表示观察对象,定义了注册观察者和删除观察者的方法。此外还声明了获取现在的状态的方法(供观察者调用)。
- ConcreteSubject(具体的观察对象):该角色表示具体的被观察对象。当自身状态发生变化后,它会通知所有已经注册的Observer角色。
- Observer(观察者):该角色负责接收来自Subject角色的状态变化的通知。声明了update方法。
- ConcreteObserver(具体的观察者)。该角色表示具体的Observer。当它的update方法被调用后,会去获取要观察的对象的最新状态。
- Observer模式的类图:
1.4 其他特点
- 需要注意Observer的update方法的调用顺序,不能因为update方法的调用顺序发生改变而产生问题。示例程序中时按照注册顺序来调用update方法的。
- Observer角色也有可能会触发Subject角色(在Observer角色中改变Subject角色的状态)调用update方法,这时,可能会导致方法被循环调用,陷入死循环:
- 实际上Observer角色并非主动地去观察,而是被动地接受来自Subject角色的通知,因此也被称为Publish-Subscribe(发布-订阅)模式。
- java.util.Observer接口和java.util.Observable类就是一种Observer模式。
- java.util.Observer接口中提供了方法:
- public void update(Observable obj, Object arg);
- Observable类的实例是被观察的Subject角色
- Object类的实例是附加信息
- 这种方式并不常用,因为Java是单继承的,传递给它的Subject角色必须继承Observable类,到那时这个Subject角色可能已经是某个类的子类了。
- 通常使用还是将Observer角色定义为接口。
- java.util.Observer接口中提供了方法:
- Servlet中的监听器也是Observer模式的一种运用。用于监控作用域对象生命周期变化时刻以及作用域对象共享数据变化时刻。
根据图解设计模式书籍进行整理。