JavaScript设计模式——观察者模式

简介: 观察者模式(也称发布订阅模式)是JavaScript中非常常见的设计模式,可以实现页面中的消息机制的监听,也是Vue、React主流框架实现的数据响应手段,解决了主体对象之间的解耦,今天来实现一下。

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

前言

观察者模式(也称发布订阅模式)是JavaScript中非常常见的设计模式,可以实现页面中的消息机制的监听,也是Vue、React主流框架实现的数据响应手段,解决了主体对象之间的解耦,今天来实现一下。

Dep发布者

class Dep {
   
            //发布者(商店)
   constructor(shopMoney, shopName) {
   
   
     this.shopMoney = shopMoney;
     this.shopName = shopName;
     this.observers = [];
   }
   setState(state) {
   
          //状态改变,通知订阅
     this.shopMoney = state;
     this.noticy();    
   }
   addObserver(ob) {
   
          //添加订阅者
     this.observers.push({
   
   
       name: ob.name,
       constructor: ob
     });
   }
   noticy() {
   
               //状态改变,发布
     this.observers.forEach(ob => {
   
   
       ob.constructor.update(`${ob.name}你好,${this.shopName}价格更新了,价格为${
     
     this.shopMoney}`)
     })
   }
 }

这里是发布者构造函数,包含商品初价,商品名称,订阅者列表,之后的订阅者创造实例时会用到addObserver方法,noticy方法用于通知每一个订阅者(observers)

Observer订阅者

class Observer {
   
           //订阅者(顾客)
  constructor(name, dep) {
   
   
    this.name = name;
    this.dep = dep;
    this.dep.forEach(d => {
   
   
      d.addObserver(this);
    })
  }
  update(val) {
   
          //改变通知
    console.log(val)
  }
}

这里订阅者可以同时订阅多个dep,并且在实例化时调用dep实例的addObserver方法。
这样就形成dep和observer的关联性。

案例

现在我们创造一家猪肉店和一家鞋店,并且可以通过input改变价格,页面如下:

!\[在这里插入图片描述\](https://ucc.alicdn.com/images/user-upload-01/db7c0cf0dd454458b179ef34f4ebce65.png
我们通过一个input函数来作为发布者改变商品价格的入口。

<span>鞋子价格</span><input type="text" oninput="changeMoney(event, 1)" value="500">
<span>猪肉价格</span><input type="text" oninput="changeMoney(event, 2)" value="30">

<script>
function changeMoney(e, id) {
   
   
  id === 1 
  ?
  dep1.setState(e.target.value)
  :
  dep2.setState(e.target.value)
}
</script>

同时构建两个dep实例和两个observer实例:

const dep1 = new Dep(500, '鞋子');
const dep2 = new Dep(30, '猪肉');
const ob1 = new Observer('顾客1', [dep1, dep2]);
const ob2 = new Observer('顾客2', [dep1]);

输入input,结果如下:

在这里插入图片描述

这样,一个简易的发布订阅模式就完成了。

源码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <span>鞋子价格</span><input type="text" oninput="changeMoney(event, 1)" value="500">
  <span>猪肉价格</span><input type="text" oninput="changeMoney(event, 2)" value="30">
</body>
<script>
  class Dep {
   
            //发布者(商店)
    constructor(shopMoney, shopName) {
   
   
      this.shopMoney = shopMoney;
      this.shopName = shopName;
      this.observers = [];
    }
    setState(state) {
   
          //状态改变,通知订阅
      this.shopMoney = state;
      this.noticy();    
    }
    addObserver(ob) {
   
          //添加订阅者
      this.observers.push({
   
   
        name: ob.name,
        constructor: ob
      });
    }
    noticy() {
   
               //状态改变,发布
      this.observers.forEach(ob => {
   
   
        ob.constructor.update(`${ob.name}你好,${this.shopName}价格更新了,价格为${
     
     this.shopMoney}`)
      })
    }
  }
class Observer {
   
           //订阅者(顾客)
  constructor(name, dep) {
   
   
    this.name = name;
    this.dep = dep;
    this.dep.forEach(d => {
   
   
      d.addObserver(this);
    })
  }
  update(val) {
   
          //改变通知
    console.log(val)
  }
}

const dep1 = new Dep(500, '鞋子');
const dep2 = new Dep(30, '猪肉');
const ob1 = new Observer('顾客1', [dep1, dep2]);
const ob2 = new Observer('顾客2', [dep1]);

function changeMoney(e, id) {
   
   
  id === 1 
  ?
  dep1.setState(e.target.value)
  :
  dep2.setState(e.target.value)
}
</script>
</html>

总结

设计模式真的很有意思,可以感受到JavaScript的灵活性,也可以为我们平时写业务逻辑提供更多的思维和解决方式。

目录
相关文章
|
2月前
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
56 3
|
17天前
|
设计模式 存储 供应链
前端必须掌握的设计模式——观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种订阅机制。它包含两个角色:**观察者**(订阅消息、接收通知并执行操作)和**被观察者**(维护观察者列表、发送通知)。两者通过一对多的关系实现解耦,当被观察者状态改变时,会通知所有订阅的观察者。例如,商店老板作为被观察者,记录客户的需求并在商品到货时通知他们。前端应用中,如DOM事件注册、MutationObserver等也体现了这一模式。
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
3天前
|
设计模式 数据安全/隐私保护
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
48 33
|
3月前
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
56 0
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
45 1
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
44 2
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
31 3
|
3月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
38 9