定义
一个主题对象,维持一个它的依赖者(观察者)的列表,当它的状态发生变化时会自动通知列表中的观察者,通常是调用观察者中的一个方法。
比如订阅消息,消息的发布者和接收者就构成了一个观察者模式。
使用
一个观察者接口及一些实现类,一个主题(Subject),Subject维护一个观察者列表,其有一些方法可以注册观察者(registerObserver),注销观察者(unregisterObserver),以及当它状态变化时通知所有的观察者(notifyObservers),在notifyObservers方法中遍历所有的观察者,调用其对应的方法,使观察者得到通知。
代码(Java)
// 观察者接口 public interface Observer { void update(); } // 观察者A public class ConcreteObserverA implements Observer { @Override public void update() { System.out.println("ConcreteObserverA has notified"); } } // 观察者B public class ConcreteObserverB implements Observer { @Override public void update() { System.out.println("ConcreteObserverB has notified"); } } // 主题(被观察者) public class Subject { // 观察者列表 Set<Observer> observerCollection = new HashSet<>(); // 注册观察者 public void registerObserver(Observer observer) { observerCollection.add(observer); } // 注销观察者 public void unregisterObserver(Observer observer) { if (observerCollection.contains(observer)) { observerCollection.remove(observer); } } // 通知所有观察者 public void notifyObservers() { for (Observer observer : observerCollection) { observer.update(); } } public static void main(String[] args) { Subject subject = new Subject(); // 注册所有观察者 subject.registerObserver(new ConcreteObserverA()); subject.registerObserver(new ConcreteObserverB()); // 当主题状态发生变化时,通知所有观察者 subject.notifyObservers(); } }
Java也提供了对应观察者模式的Observable类和Observer接口,可以直接使用。
总结
使用观察者模式让系统松耦合,主题只知道观察者实现了某个接口。主题不需要知道观察者的具体类是谁、做了些什么活其他任何细节。有新类型的观察者出现时,主题的代码不需要修改。改变主题或观察者其中一方,并不会影响另一方。因为两个是松耦合的。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。