前端小白变形记:你要学会这些设计模式!第四弹:观察者模式

前言

  1. 从第一篇工厂模式开始,我会持续地更新每一种设计模式的内容,争取用通俗易懂的语言讲解和解释清楚。如果对你学习设计模式有帮助,请不要吝啬手中的赞~ 如果对文章内容有任何疑惑都可以在评论区提出和讨论~

  2. 本系列文章中的完整源码已上传 github 仓库,你可以在这里 github.com/FatMii/Desi...获取。

    同样的,如果对你有帮助,请给我一个star~谢谢

  3. 设计模式合集链接:

    前端小白变形记:你要学会这些设计模式!首发:工厂模式

    前端小白变形记:你要学会这些设计模式!第二弹:单例模式

    前端小白变形记:你要学会这些设计模式!第三弹:责任链模式

    前端小白变形记:你要学会这些设计模式!第四弹:观察者模式

Hello~大家好,前面三篇我们已经学习工厂模式单例模式责任链模式观察者模式。本篇我们继续学习第四种设计模式:观察者模式

观察者模式是什么呢?想象一下,你是一个热心的邻居,总爱窥探你家对面的老王家的动静。每当老王家开派对,你就知道得装作无意走过,加入狂欢。这里,老王家就是被观察者,而你,这个总爱"偶遇"的热心邻居,就是观察者。简单来说,观察者模式就是:一个对象变得有趣了,所有关注它的对象都会收到通知,并且自动更新自己的状态------"嘿,老王家又开派对了!"

现在,让我们用一个日常生活中的例子来说明这一点:

假设你的微信里关注了"美食探索"公众号。这里,"美食探索"就是那个老王,也就是被观察者,而你和其他几千个饥饿的粉丝就是观察者们。这种关系,就是一对多的关系一个公众号,无数观众。每当公众号推出新的烧烤技巧或者最新的美食攻略时,所有的粉丝(也就是观察者们)都会立刻收到推送!

代码实现

javascript 复制代码
// 应用场景:1.dom监听 2.降价商品
class Subject {
  constructor() {
    this.Observers = [];
  }
  add(observer) {
    this.Observers.push(observer);
  }
  remove(observer) {
    this.Observers = this.Observers.filter((item) => item !== observer);
  }
  notify() {
    this.Observers.forEach((item) => {
      item.update();
    });
  }
}
//定义观察者对象
class Observer {
  constructor(name) {
    this.name = name;
  }
  update() {
    console.log(`my name is:${this.name}`);
  }
}

let sub = new Subject();
let obs1 = new Observer("observer11");
let obs2 = new Observer("observer22");
sub.add(obs1);
sub.add(obs2);
sub.notify();

console.log("删除obs1后再次通知:")
sub.remove(obs1);
sub.notify();

// my name is:observer11
// my name is:observer22
// 删除obs1后再次通知:
// my name is:observer22

Subject 类(被观察者)

  1. 构造函数 : Subject 类有一个构造函数,初始化一个空数组 Observers,用来存储所有观察者对象。
  2. add 方法 : 用于添加一个新的观察者对象到 Observers 数组中。
  3. remove 方法 : 用于从 Observers 数组中移除一个指定的观察者对象。这里使用 filter 方法来创建一个不包含被移除观察者的新数组,从而实现删除功能。
  4. notify 方法 : 遍历 Observers 数组中的每个观察者,并调用他们的 update 方法。这个方法在被观察者状态改变时被调用,用以通知所有观察者。

Observer 类(观察者)

  1. 构造函数 : 每个 Observer 对象在创建时接受一个 name 参数,这个名称被存储在对象属性中,用于标识不同的观察者。
  2. update 方法 : 当被观察者调用 notify 方法时,update 被执行,输出一个包含观察者名称的消息。这里的 update 方法可以根据实际需要进行更复杂的逻辑扩展。

优点

  1. 支持广播通信:观察者模式支持广播方式的通信,被观察者可以无差别地通知所有注册的观察者,无需关心观察者的具体实现,这有利于事件驱动的程序设计。
  2. 动态添加和删除观察者:在观察者模式中,可以随时增加和删除观察者,这使得系统更加灵活,并易于扩展和修改。
  3. 符合开闭原则:新的观察者可以很容易地添加进系统中,而不必修改主体(被观察者)的代码。系统可以在运行时通过添加和移除观察者来增强或修改功能,符合开闭原则。

缺点

  1. 可能导致效率问题:如果观察者数量很多,且更新操作频繁,每次状态变化都会导致所有的观察者被通知和更新,这可能会消耗大量的计算资源或处理时间,尤其是在大型系统中。

  2. 更新的无序性:观察者被通知的顺序可能是不确定的,尤其是在异步处理模型中。这可能会导致在状态更新和数据一致性上的问题,特别是当观察者对数据的一致性有严格要求时。

相关推荐
马剑威(威哥爱编程)13 分钟前
MongoDB面试专题33道解析
数据库·mongodb·面试
小远yyds15 分钟前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端1 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱1 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai1 小时前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
独行soc2 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
王哲晓3 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js