首页 > 其他分享 >前端设计模式:观察者与发布订阅模式

前端设计模式:观察者与发布订阅模式

时间:2023-02-10 12:31:29浏览次数:48  
标签:订阅 console log LIST girls 观察者 设计模式 name

观察者模式

描述:

观察者模式(Observer Pattern)由被观察者和观察者组成,观察者可以是多个,被观察者维护着多个观察者,如添加或删除观察者;当被观察着数据变化时,会通过广播的方式通知维护的每一个观察者(即调用观察者提供的回调函数)。

概要:

观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知

举个栗子:

小美通过自己的努力吸引了2个追求者.小美每次发朋友圈必定会得到两个追求者的回应.小美与两个追求者的关系形成了观察者模式.小美是被观察者,两个舔狗是观察者.小美发朋友圈这个动作会触发舔狗的回应

// 被观察者
class ABeautifulGirl {
  TIAN_GOU_LIST = [] // 舔狗们
  // 添加观察者
  attractTianGou(...tianGous) {
    Array.prototype.push.apply(this.TIAN_GOU_LIST, tianGous)
  }
  // 删除观察者
  kickOffTianGou(tianGou) {
    const index = this.TIAN_GOU_LIST.indexOf(tianGou)
    this.TIAN_GOU_LIST.splice(index, 1)
  }
  // 女神技能:发朋友圈(发布通知)
  sendPost(data) {
    this.TIAN_GOU_LIST.forEach(tianGou => {
      tianGou.callback.call(tianGou, data)
    })
  }
}
// 观察者
class TianGou {
  constructor(name, fn) {
    this.name = name
    this.lick = fn
  }
  callback(data) {
    console.log(
      `我是${this.name}今天女神发朋友圈说她${data},我要给女神发信息:`
    )
    this.lick()
  }
}
// 定义两个观察者
const tiangou1 = new TianGou('tiangou1', () => {
  console.log('多喝热水')
})
const tiangou2 = new TianGou('tiangou2', () => {
  console.log('请一定要多喝热水呀')
})
// 小美通过自己的努力有了吸引别人关注的能力
const xiaomei = new ABeautifulGirl()
xiaomei.attractTianGou(tiangou1, tiangou2)
// 小美发了个朋友圈
xiaomei.sendPost('肚子疼')

image.png

再举个栗子

舔狗舔了数次始终没有的到小美的青睐, 这次他学会了主动, 他准备再勾搭一个女神, 于是他想办法加了小丽的微信, 开始了同时对两人的观察.

class ABeautifulGirl {
  constructor(name) {
    this.name = name
  }
  TIAN_GOU_LIST = []
  sendPost(data) {
    console.log(`${this.name},发个朋友圈`)
    this.TIAN_GOU_LIST.forEach(tianGou => {
      tianGou.callback.call(tianGou, data)
    })
  }
}
// 观察者:(主动)关注或取消关注
class TianGou {
  constructor(name, fn) {
    this.name = name
    this.lick = fn
  }
  subscribe(publish) {
    var sub = this
    var alreadyExists = publish.TIAN_GOU_LIST.some(function (item) {
      return item === sub
    })
    // 如果女神的好友名单中没有这个人,则加入进去
    if (!alreadyExists) publish.TIAN_GOU_LIST.push(sub)
    return this
  }
  unsubscribe(publish) {
    var sub = this
    publish.TIAN_GOU_LIST = publish.TIAN_GOU_LIST.filter(function (item) {
      return item !== sub
    })
    return this
  }
  callback(data) {
    console.log(
      `    ${this.name} 看到女神发朋友圈说她 ${data} ,我要给女神发信息:`
    )
    this.lick()
  }
}
// 小美 & 小丽
const xiaomei = new ABeautifulGirl('xiaomei')
const xiaoli = new ABeautifulGirl('xiaoli')
// 两个舔狗
const tiangou1 = new TianGou('tiangou1', () => {
  console.log('    多喝热水')
})
const tiangou2 = new TianGou('tiangou2', () => {
  console.log('    请一定要多喝热水呀')
})
// 舔狗主动订阅女神们的消息
tiangou1.subscribe(xiaomei).subscribe(xiaoli)
tiangou2.subscribe(xiaomei)
// 小美小丽肚子疼
xiaomei.sendPost('肚子疼')
xiaoli.sendPost('腰子疼')

image.png

优缺点:

  优点明显:降低耦合,两者都专注于自身功能;   缺点也很明显:所有观察者都能收到通知,无法过滤筛选;

发布订阅模式

Publisher && Subscriber

描述:

舔狗们订阅了很多女神, 但大都无疾而终, 舔狗中有一只聪明狗, 姑且就叫它二哈吧, 二哈首先意识到, 女神们生病的时候只是发 [多喝热水] 是没有用的, 还要在早上对女神说早上好, 下班了对女生下班好, 去输液了要对女神说说输的的想你的夜. 二哈开始行动了, 于是二哈学习了发布订阅模式.

概要:

发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。 发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。

举个栗子:

const GirlsHub = function () {
  this.grils = {}
  this.on = function (name, cb) {
    if (this.grils[name]) {
      this.grils[name].push(cb)
    } else {
      this.grils[name] = [cb]
    }
  }
  this.trigger = function (name, ...arg) {
    if (this.grils[name]) {
      this.grils[name].forEach(eventListener => {
        eventListener(...arg)
      })
    }
  }
}
let girls = new GirlsHub()
girls.on('morring', () => {
  console.log('对小美说早安')
})
girls.on('morring', () => {
  console.log('对小丽说早安')
})
girls.on('morring', () => {
  console.log('对小美丽说早安')
})
girls.on('noon', () => {
  console.log('对小美说午安')
})
girls.on('noon', () => {
  console.log('对小丽说午安')
})
girls.on('noon', () => {
  console.log('对小美丽说午安')
})
girls.on('evening', () => {
  console.log('对小美说晚安')
})
girls.on('evening', () => {
  console.log('对小丽说晚安')
})
girls.on('evening', () => {
  console.log('对小美丽说晚安')
})
girls.trigger('morring')
girls.trigger('noon')
girls.trigger('evening')

image.png

学会之后,二哈化被动为主动, 每到时辰就开始给女神们发消息, 本以为能够收获女神们的芳心,到后来发现,自己被一半人都拉黑了.

看来功力还不够深厚啊.需要学习以下其他的设计模式来优化以下方案。

优缺点:

  优点:解耦更好,细粒度更容易掌控;

  缺点:不易阅读,额外对象创建,消耗时间和内存

两种模式的关联和区别

发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。

  1. 观察者模式维护单一事件对应多个依赖该事件的对象关系;
  2. 发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;
  3. 观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象);
  4. 观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。

标签:订阅,console,log,LIST,girls,观察者,设计模式,name
From: https://blog.51cto.com/codeniu/6049085

相关文章

  • 设计模式(七)----创建型模式之建造者模式
    1、概述将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。分离了部件的构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的......
  • 国民应用QQ如何实现高可用的订阅推送系统
    国民应用QQ如何实现高可用的订阅推送系统https://mp.weixin.qq.com/s/4cjFM4XOlzu07QI3gswWoQ国民应用QQ如何实现高可用的订阅推送系统原创 许扬 腾讯云开发者 2023-......
  • 6 mvvm设计模式
    Vue的createApp和mount方法讲解​​简介​​​​最常见的Vue初级代码​​​​createApp()和mount()方法讲解​​​​createApp()方法的基本参数讲解​​​​如何获......
  • 设计模式
    一.设计模式分为1.创建型模式2.结构型模式3.行为型模式二.创建型模式1.简单工厂(工厂方法)模式:隐藏创建对象的细节,在使用时才选择创建哪个对象(建议使用反射);就是一个......
  • React:消息订阅(subscribe)-发布(publish)机制
    发布类似触发事件, 订阅类似监听事件使用这种方式的好处是,兄弟组件间通信不必再像使用props那种通过父组件来通信,多层组件之间通信也不必在一层一层的传递,直接在触发事件......
  • 常用设计模式 每一个demo 和每一个大或者小的项目, 想写好代码,都会用到
    设计原则①单一职责原则(SRP)使函数或对象功能尽量单一,应该把对象或方法划分成较小的粒度②最少知识原则(LKP)自我理解:最少知识指最少地知道认识;简而言之就是尽量降低方法或模......
  • 谈谈我工作中的23个设计模式
    作者:闵大为(天未)序从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行......
  • 软件设计模式
    有人说设计模式大致总结为23种,有人说29种,各式各样。我们讨论的不限于23种,关键掌握的是一些常用的设计模式。编程时一种技术,更加是一门艺术。不能只满足于写完代码运行结果正......
  • 设计模式-建造者模式
    建造者模式builderModle.h#pragmaonce#include<iostream>#include<string>usingnamespacestd;classPhone{public: Phone(){} ~Phone(){} voidsetB......
  • 设计模式-单例模式
    简易单例模型easysiglemodle.h#ifndefEASYSIGLEMODLE_H#defineEASYSIGLEMODLE_H#include<iostream>usingnamespacestd;classEasySingleModle{public:......