zoukankan      html  css  js  c++  java
  • 设计模式 Observer

    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

    Dependents, Publish-Subscribe

    将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。

    适用性:

    • 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。
    • 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
    • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。

    结构

    Subject

    • Subject知道它的Observer。可以有任意多个Observer观察同一个Subject。
    • 提供注册和删除Observer对象的接口。

    Observer

    • 为那些在Subject发生改变时需获得通知的对象定义一个更新接口。

    ConcreteSubject

    • 将有关状态存入各ConcreteObserver对象。
    • 当它的状态发生改变时, 向它的各个Observer发出通知。

    ConcreteObserver

    • 维护一个指向ConcreteSubject对象的引用。
    • 存储有关状态,这些状态应与Subject的状态保持一致。
    • 实现Observer的更新接口以使自身状态与目标的状态保持一致。

    允许你独立的改变Subject和Observer。

    优缺点:

    • V Subject和Observer间的抽象耦合
    • V 支持广播通信
    • X 意外的更新

    1. 创建Subject到其Observer之间的映射

    最简单的方法:显式地在Subject中保存对Observer的引用

    时间换空间:用一个关联查找机制(如hash表)来维护Subject到Observer的映射

    2. 观察多个Subject

    必须扩展Update接口以使Observer知道是哪一个Subject送来的通知

    Subject对象可以简单地将自己作为Update操作的一个参数

    3. 谁触发更新

    A 由Subject对象的状态设定操作在改变Subject对象的状态后自动调用Notify

    B 让用户负责在适当的时候调用Notify

    4. 对已删除Subject的悬挂引用

    当一个Subject被删除时,让它通知它的Observer将对该Subject的引用复位

    5. 在发出通知前确保Subject的状态自身是一致的

    抽象的Subject类中的模板方法发送通知:定义那些子类可以重定义的原语操作, 并将Notify作为模板方法中的最后一个操作

    6. 避免特定于Observer的更新协议—推/拉模型

    推(Push)模型:Subject向Observer发送关于改变的详细信息, 而不管它们需要与否

    拉(Pull)模型:Subject除最小通知外什么也不送出,而在此之后由Observer显式地向Subject询问细节

    7. 显式地指定感兴趣的改变

    扩展Subject的注册接口,让各Observer注册为仅对特定事件感兴趣,以提高更新的效率

    Aspect:

    void Subject::Attach(Observer*, Aspect& interest);
    
    void Observer::Update(Subject*, Aspect& interest);

    8. 封装复杂的更新语义

    当目标和观察者间的依赖关系特别复杂时, 可能需要一个维护这些关系的对象,即更改管理器(ChangeManager)

    目的是尽量减少Observer反映其Subject的状态变化所需的工作量

    责任:

    • 将一个Subject映射到它的Observer并提供一个接口来维护这个映射
    • 定义一个特定的更新策略
    • 根据一个Subject的请求, 更新所有依赖于这个Subject的Observer

    9. 结合Subject类和Observer类

    用不支持多重继承的语言书写的类库通常不单独定义Subject和Observer类, 而是将它们的接口结合到一个类中

  • 相关阅读:
    JS之显式类型转换(最全)
    Python如何以两个字符一行方式输出"Hello World"
    封装localstorage为插件挂载到vue原型上
    封装localstorage 为方法
    input radio checkbox选中的c's's
    vue-插件 引用ali.JS,
    时间相加减
    mall-vue 门店版
    account.vue 以及continuePay.vue 通过action 里面的ajax后去支付
    service/axios.js
  • 原文地址:https://www.cnblogs.com/chenkkkabc/p/3132597.html
Copyright © 2011-2022 走看看