图解设计模式
来源:互联网 发布:淘宝新版怎样发布宝贝 编辑:程序博客网 时间:2024/06/06 14:02
读书笔记 仅供参考
简述
观察者模式,当观察对象的状态发生变化时,会通知给观察者。适用于根据对象状态进行相应处理的场景。
角色和 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 并不是主动的去观察,而是被动的接收通知
阅读全文