• 设计模式-----观察者模式


    一、概念

    1、Observer模式的概念       

          (Observer)被称作发布-订阅者模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合。      

          (Observer)模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。     

    好处:

    • 可广泛应用于异步编程中,是一种替代传递回调函数的方案。       
    • 可取代对象之间硬编码的通知机制,一个对象不用再显示地调用另外一个对象的某个接口。 两对象轻松解耦。          

    2、Observer模式的角色       

    Subject(被观察者)        

    被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。         

    ConcreteSubject -- 被观察者的具体实现。包含一些基本的属性状态及其他操作。       

    Observer(观察者)         

    接口或抽象类。当Subject的状态发生变化时,Observer对像将通过一个callback函数得到通知。   

    ConcreteObserver -- 观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。     

    二、 应用场景

     

    1. /**
    2.   * 发布订阅模式(观察者模式)
    3.   * handles: 
    4.   * on: 订阅事件
    5.   * emit: 发布事件
    6.   * off: 删除事件
    7.  **/
    8. class PubSub {
    9.   constructor() {
    10.     this.handles = {} // 事件处理函数集合
    11.   }
    12.   //订阅事件
    13.   on(eventType, handle) {
    14.     if (!this.handles.hasOwnProperty(eventType)) {
    15.       this.handles[eventType] = []
    16.     }
    17.     if (typeof handle == 'function') {
    18.       this.handles[eventType].push()
    19.     } else {
    20.       throw new Error('缺少回调函数')
    21.     }
    22.     return this;
    23.   }
    24.   // 发布事件
    25.   emit(eventType, ...args) {
    26.     if (this.handles.hasOwnProperty(eventType)) {
    27.       this. Handles[eventType].forEach((item, key, arr) => {
    28.         item.apply(null, args)
    29.       })
    30.     } else {
    31.       throw new Error(`"${eventType}"事件未注册`)
    32.     }
    33.     return this;
    34.   }
    35.   // 删除事件
    36.   off(eventType, handle) {
    37.     if (!this.handles.hasOwnProperty(eventType)) {
    38.       throw new Error(`"${eventType}"事件未注册`)
    39.     } else if (typeof handle != 'function') {
    40.       throw new Error('缺少回调函数')
    41.     } else {
    42.       this.handles[eventType].forEach((item, key, arr) => {
    43.         if (item == handle) {
    44.           this.handles[eventType].splice(key, 1)
    45.         }
    46.       })
    47.     }
    48.     return this;
    49.   }
    50. }
    51. let pubsub = new PubSub();
    52. function callback() {
    53.   console.log('you are so nice')
    54. }
    55. // 订阅:如下在事件eventTypeName上添加了两个回调
    56. pubsub.on('eventTypeName'(...args) => {
    57.   console.log(args.join(' '))
    58. }).on('eventTypeName', callback)
    59. // 发布:
    60. pubsub.emit('eventTypeName''whar''a''fucking day'); //发布 依次执行 eventTypeName 事件中的 所以方法
    61. pubsub.off('eventTypeName', callback)  // 删除只是删除 eventTypeName 事件的 callback 方法
    62. pubsub.emit('eventTypeName''fucking''again')
    63. /*
    64.   输出值:
    65.   what a fucking day
    66.   you are so nice
    67.   fucking again
    68. */

     总结:   发布—订阅模式的优点非常明显,一为时间上的解耦,二为对象之间的解耦。它的应用非常广泛,既可以   用在异步编程中,也可以帮助我们完成更松耦合的代码编写。发布—订阅模式还可以用来帮助实现一些别   的设计模式,比如中介者模式。从架构上来看,无论是 MVC 还是 MVVM, 都少不了发布—订阅模式的参   与,而且JavaScript本身也是一门基于事件驱动的语言。   当然,发布—订阅模式也不是完全没有缺点(浪费内存)。创建订阅者本身要消耗一定的时间和内存,   而且当你订阅一个消息后,也许此消息最后都未发生,但这个订阅者会始终存在于内存中。另外,发   布—订阅模式虽然可以弱化对象之间的联系,但如果过度使用的话,对象和对象之间的必要联系也将被   深埋在背后,会导致程序难以跟踪维护和理解。特别是有多个发布者和订阅者(b订阅a的消息并发布   给c)嵌套到一起的时候,要跟踪一个bug不是件轻松的事情。

  • 相关阅读:
    maven项目打包成war包并部署到tomcat上
    关于Chrome DevTool
    数据结构之杨辉三角
    为什么Python常年排行第一第二?
    Vue之vue-cli搭建SPA项目
    最新最管用的nvm安装步骤及nvm报443超时解决方案
    程序员的数学课11 灰度实验:如何设计灰度实验并计算实验的收益?
    CAS(compare and swa)中的ABA问题及解决
    PLSQL下载并安装
    Leetcode—260.只出现一次的数字III【中等】
  • 原文地址:https://blog.csdn.net/qq_15557073/article/details/137089343