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

前言

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

相关推荐
王解3 分钟前
一篇文章读懂 Prettier CLI 命令:从基础到进阶 (3)
前端·perttier
乐闻x8 分钟前
最佳实践:如何在 Vue.js 项目中使用 Jest 进行单元测试
前端·vue.js·单元测试
遇到困难睡大觉哈哈20 分钟前
JavaScript面向对象
开发语言·javascript·ecmascript
檀越剑指大厂23 分钟前
【Python系列】异步 Web 服务器
服务器·前端·python
我是Superman丶25 分钟前
【前端】js vue 屏蔽BackSpace键删除键导致页面后退的方法
开发语言·前端·javascript
Hello Dam26 分钟前
基于 Spring Boot 实现图片的服务器本地存储及前端回显
服务器·前端·spring boot
小仓桑28 分钟前
利用 Vue 组合式 API 与 requestAnimationFrame 优化大量元素渲染
前端·javascript·vue.js
Hacker_xingchen28 分钟前
Web 学习笔记 - 网络安全
前端·笔记·学习
天海奈奈29 分钟前
前端应用界面的展示与优化(记录)
前端
就是有点傻41 分钟前
C#中面试的常见问题006
开发语言·面试·c#·wpf