-
意图:
定义对象间地一种一对多地依赖关系,当一个对象地状态发生改变时,所有对于依赖于它的对象都得到通知并被自动更新。 -
别名:
依赖(Dependents), 发布-订阅(Publish-Subsribe) -
动机:
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维护一致性而是各类紧密耦合,这样降低了它们的可重用性。 -
适用性:
在以下任一情况下可以使用观察者模式:
a. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
b. 当一个对象必须通知其它对象,而它有不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。 -
结构:
-
参与者:
a. Subject:
目标知道它的观察者。可以有多个观察者观察同一个目标。
提供注册和删除观察者对象的接口。
b. Observer:
为那些在目标发生改变时需获得通知的对象定义一个跟新接口。
c. ConcreteSubject:
将有关状态 存入各ConcreteObserver
当它的状态发生改变时,向它的各个观察者发生通知。
d. ConcreteObserver:
维护一个指向ConcreteSubject对象的引用。
存储有关状态,这些状态应与目标的状态保持一致。
实现Observer的更新接口以使自身状态与目标的状态保持一致。 -
协作:
-
效果:
a. 目标和观察者间的抽象耦合
b. 支持广播通信
c. 意外的更新 -
实现:
a. 创建目标到其观察者之间的映射
b. 观察多个目标
c. 谁触发更新
d. 对已删除目标悬挂引用
e. 在发出通知前确保目标的状态自身是一致的
f. 避免特定于观察者的更新协议–推/拉模式
g. 显式地指定感兴趣的改变
h. 封装复杂的更新语义
i. 结合目标类和观察者 -
代码示例:
public interface Observer {void update();}public interface Subject {void attach(Observer observer);void detach(Observer observer);void notify2();}public class ConcreteSubject implements Subject {private int state;private List<Observer> observers = new ArrayList<>();@Overridepublic void attach(Observer observer) {observers.add(observer);}@Overridepublic void detach(Observer observer) {observers.remove(observer);}@Overridepublic void notify2() {for (Observer observer : observers) {observer.update();}}public int getState() {return state;}public void setState(int state) {this.state = state;notify2();}}public class ConcreteObserver implements Observer{private int observerState;private ConcreteSubject subject;public ConcreteObserver(ConcreteSubject subject) {this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {observerState = subject.getState();System.out.println("Observer state update: " + observerState);}}public class Client {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer1 = new ConcreteObserver(subject);ConcreteObserver observer2 = new ConcreteObserver(subject);subject.setState(10);subject.setState(20);subject.detach(observer1);subject.detach(observer2);}}
-
已知应用:
-
相关模式:
Mediator:通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介者。
Singleton: ChangeManager可使用Singleton模式来保证它是唯一的并且是可全局访问的。