观察者模式学习总结
Jiacheng / 2016-08-18
模式特点
- 也称为发布—订阅模式(Publish-Subscribe)
- 对象行为型模式
- 一个被观察者可以同时被多个观察者监听观察。被观察者发生变化时会通知所有的观察者。可以根据需要增加和删除观察者,使得系统便于扩展。
解决的问题
- 对象之间的联动。
- 用于建立对象与对象之间的依赖关系,一个对象发生改变时自动通知其他相关依赖对象,相关的依赖对象会自动更新。
- 当多个类之间的协作,需要维护相关的对象的一致性时,降低类和类之间的耦合性,提高可维护性,可扩展性,可重用性。
包含的角色
- 观察目标(Subject):又称主题,被观察的对象。目标中定义了一个观察者(数量不限)的集合,提供方法来增加和删除观察者对象,定义了通知方法 notify()。目标类可以是接口,也可以是抽象类或具体类。
- 具体目标(ConcreteSubject):具体目标是目标的子类,通常包含有经常发生改变的数据,当它的状态发生改变时,会向观察者发出通知。同时,实现了目标类中定义的抽象业务逻辑方法(如果有)。如果无需扩展目标类,则具体目标类可以省略。
- 观察者(Observer)观察者对观察目标的改变做出反应,一般定义为接口,接口中声明更新数据的方法 update(),因此又称为抽象观察者。
- 具体观察者(ConcreteObserver):在具体观察者中维护着一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态和具体目标的状态保持一致。实现了抽象观察者中的 update() 方法。通常在实现时可用调用具体目标类的 attach() 方法将自己添加到目标类中观察者集合,或通过 detach() 方法将自己从集合中删除。
主要优点:
- 实现表现层与数据逻辑层的分离,定义了稳定的消息更新传递机制,抽象了等更新接口,使得可以有各种各样的不同的表现层充当具体观察者的角色。
- 在观察目标和观察者之间建立了抽象的耦合。观察目标只需维护一个抽象观察者的集合,无须了解具体观察者。由于观察者和观察目标没有紧密的耦合在一起,所以他们可以属于不同的抽象化层次。
- 观察者模式支持广播通信,观察目标会向所有的观察者对象发送通知,简化了一对多系统设计的难度。
- 观察者模式满足“开闭原则”,增加新的观察者无须修改原油系统的代码。在具体的观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
主要缺点:
- 直接观察者和间接观察者有很多话,通知所有的观察者会花费很多时间。
- 如果观察目标与观察者之间存在循环依赖,观察目标会触发它们之间的循环调用,有可能导致系统崩溃。
- 观察者无法知道观察目标是如何变化的,仅仅观察目标发生了变化。没有相应的机制实现这一点。
适用场景:
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将两个方面封装在独立的对象中,使它们可以各自独立地改变和复用。
- 一个对象的改变导致一个或多个其他对象也发生改变,而且并不知道有多少个对象将发生改变,也不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为影响B,B影响C·····,可以使用观察者模式创建一种链式触发机制。
模式的扩展
MVC模式是一种架构模式,可以看成是观察者模式的一种扩展实现。MVC模式中包含三个角色,模型(Model),视图(View),控制器(Controller),其中控制器是模型与视图之间的中介。当Model层的数据 发生改变时,View层会自动改变相应的显示内容。