发布订阅者模式的理解和应用

详解

ps:什么是设计模式
是设计思路,一定程度提高效率
在基础的23中设计模式中进行使用和优化和改良。

1.发布-订阅者模式定义

  • 发布-订阅者模式其实是一种对象间一对多的依赖关系(利用消息队列)
  • 当一个对象(state)的状态发生改变时,所有依赖于它的对象都得到状态改变的通知
  • 订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel)
  • 当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时。
  • 由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码

2.特征

  • 基本事件调用过程
    先定义一个普通函数/事件
    然后调用
  • 发布订阅者模式,则是为了让发布者和订阅者解耦(在发布者和订阅者中间增加一个调度中心)
  • 发布订阅者模式是一对多的关系(一个调度中心对应多个订阅者)
  • 发布订阅者模式通常会有一个对应消息队列(Array相当于queue)数组的概念[fn1, fn2, fn3]先进先出
  • 先定义好消息队列,需要的对象去订阅。当状态改变,对象不再主动触发,而是被动接收。

3.发布订阅者模式的实现思路

  • 创建一个类
  • 在该类上创建一个缓存列表(调度中心)
  • on方法用来把函数fn都加到缓存列表(订阅者注册事件到调度中心)
  • emit方法取到event事件类型,根据event值去执行对应缓存列表中的函数(发布者发布事件到调度中心,调度中心处理代码)
  • off方法可以根据event事件类型取消订阅

案例讲解

  1. 去书店买书
  • 普通模式:频繁的去调用相应的办法。
    去书店,问,没有,回家
    过一会再去,问,没有,回家
    过一会再去,问,没有,回家
    实现思想之一-轮询:setInterval,websocret
    影响:网络的负担
  • 发布订阅者模式
    去书店,问,没有,订阅(on)一个联系方式给店员
    有了书,店员就发射(emit)一个电话给用户,触发消息队列(message)去买书。如果我已经买到书,就回复,我已经买到书了 ,不要了off()。
    四个部分:message,on,emit,off
    emit部分的表现形式:老的框架如jquery-》fire,还有trigger。
    实现思想之一-绑定事件:比如给事件绑定点击事件,当点击时,状态发生改变,触发点击事件。(可以理解为发布订阅者模式在前端无处不在)

案例分析

// 1.创建一个分析构造函数类
    // 包括4部分(消息队列,$on向消息队列里添加内容,$off删除消息队列里的内容,$emit触发消息队列里面的内容)
// 2.使用构造函数创建一个实例
// 3.使用实例,$on向消息队列里添加内容,$off删除消息队列里的内容,$emit触发消息队列里面的内容
/**
     * 分析构造函数
     * + 属性: 消息队列
     * {
     *  "click":[fn1, fn2, fn3],
     *  "abc":[fnA, fnB]
     * }
     * + 能向消息队列里面添加内容 $on
     * + 删除消息队列中的内容 $off
     * + 触发消息队列里面的内容 $emit
     */
    // 新建类
    class Observer {
      // 新建构造器
      constructor() {
        this.message = {}
      }
      // type 我拜托你要看着的某个行为
      // fn 行为发生之后应该做什么事情
      $on(type, fn) {
        // 先判断有没有这个属性
        // 如果没有这个属性,就初始化一个空的数组
        // 如果有这个属性,就往他的后面push一个新的fn
        // this.message[type] = fn
        if(!this.message[type]) {
          this.message[type] = []
        }
        this.message[type].push(fn)
      }
      $off(type, fn) {
        //判断有没有订阅
        if(!this.message[type]) return
        //判断有没有fn这个参数
        //如果没有fn,我就删掉整个事件
        if(!fn){
          this.message[type] = undefined
          return
          // 官方方法
          //delete this.message[type] 
        }
        //如果有fn我就仅仅只是过滤掉这个方法
        this.message[type] = this.message[type].filter((item) => item !== fn)
      }
      $emit(type) {
        //判断是否订阅
        if(!this.message[type]) return
        this.message[type].forEach(item => {
          item()
        })
      }
    }
    // 使用构造函数创建一个实例
    const person1 = new Observer() // 观察者

   
    // 向person1委托一些内容,帮忙观察
    person1.$on("abc", handlerA)
    person1.$on("abc", handlerB)

    
    // 整个消息队列全部删掉
    // person1.$off("abc")
    // 删掉部分消息队列
    // person1.$off("abc",handlerA)
    person1.$emit("abc")
    console.log(person1);

    // person1.$on("黑书", handlerA)
    // person1.$on("黑书", handlerB)

    // person1.$on("白书", handlerB)
    // person1.$on("白书", handlerC)


    function handlerA() {
      console.log("handlerA");
    }
    function handlerB() {
      console.log("handlerB");
    }
    function handlerC() {
      console.log("handlerC");
    }

知识点发散

设计模式有哪些

  1. 结构型模式
  • 桥接模式
  • 适配器模式
  • 装饰器模式
  • 代理模式
  • 外观(门面)模式
  • 组合模式
  1. 创建型模式
  • 建造者模式
  • 单例模式
  • 抽象工厂模式
  • 工厂方法模式
  • 静态工厂模式
  1. 行为型模式
  • 模版方法模式
  • 策略模式
  • 观察者模式
  • 责任链模式
  • 命令模式
  • 访问者模式

你可能感兴趣的:(发布订阅者模式的理解和应用)