JavaScript - 观察者模式的实现与应用场景

1. 什么是观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系。当主题带有的状态被改变时,所有观察者都会收到通知并自动更新。

主题(Subject):Subject也可以称为被观察者,它维护一个Observer列表,实现新增、删除、通知Observer更新的方法。

观察者(Observer):Observer是接收主题通知的对象,需要实现一个更新方法,当收到Subject的通知时,调用该方法进行更新。

具体主题(Concrete Subject):ConcreteSubject继承了Subject,是Subject的具体实现类,我们在其中定义主题状态,当状态发生某些变化时通知Observer更新。

具体观察者(Concrete Observer):ConcreteObserver是Observer的具体实现类。它定义了在收到通知时需要执行的具体操作。

需要注意的是,在观察者模式的依赖关系中,并不是观察者主动拉取主题消息,而是被动的接收主题通知并产生相应变化

2. 观察者模式举例

以拍卖会上拍卖者与竞价者的一对多的依赖关系举例:当价格更新时,所有的竞价者都会收到通知。

3. 例子的代码实现

定义Subject类与Observer类

javascript 复制代码
/**
 * 主题(Subject)中维护一个观察者列表,实现新增、删除观察者、与通知观察者更新的方法
 */
class Subject {
  constructor() {
   this.observerList = [];
  }
  
  /**
   * 新增观察者方法
   * @param observer
   */
  addObserver(observer) {
   this.observerList.push(observer);
  }
  
  /**
   * 移除观察者方法
   * @param observer
   */
  removeObserver(observer) {
   const findBidderIndex = this.observerList.findIndex(observerItem => {
    return observerItem.id === observer.id;
   })
   if(findBidderIndex > -1) {
    this.observerList.splice(findBidderIndex, 1);
   }
  }
  
  /**
   * 通知观察者进行更新
   * @param data
   */
  notify(data) {
   this.observerList.forEach(observerItem => {
    observerItem.update(data);
   })
  }
}

/**
 * 观察者(Observer)中应定义一个更新方法
 */
class Observer {
  
  /**
   * 更新方法
   * @param data
   */
  update(data) {
  }
}

定义Subject与Observer的具体类

scala 复制代码
/**
 * 定义一个拍卖师类,作为具体主题(ConcreteSubject)
 */
class Auctioneer extends Subject {
  constructor() {
   super();
   this.state = '30';
  }
  
  setState(state){
   this.state = state;
   this.notify(this.state);
  }
  
  getState(){
   return this.state;
  }
}

/**
 * 定义一个竞拍者类,作为具体观察者(ConcreteObserver),实现update方法
 */
class Bidder extends Observer {
  constructor(id) {
   super();
   this.id = id;
  }
  
  update(data) {
   console.log('竞拍者 ' + this.id + ' 收到通知:' + data);
  }
}

创建实例、修改状态

ini 复制代码
//实例化具体主题
const auctioneer = new Auctioneer();

//实例化具体观察者
const bidder1 = new Bidder(1);
const binder2 = new Bidder(2);
const binder3 = new Bidder(3);

//将具体观察者推入具体观察者列表
auctioneer.addObserver(bidder1);
auctioneer.addObserver(binder2);
auctioneer.addObserver(binder3);
auctioneer.removeObserver(binder2);

//修改状态
auctioneer.setState(20);

打印结果

复制代码
竞拍者 1 收到通知:20
竞拍者 3 收到通知:20

4.观察者模式的适用场景

当目标对象与其它对象产生一对多关系时,当目标对象改变,希望其它对象也发生相应变化

比如在订单页面使用v-for生成出来几个Tab组件,通过滑动切换。这些Tab页标识着该用户所有订单的状态。

当用户操作的某一笔订单的状态发生改变时,我们希望每个与该笔订单相关的所有Tab组件都发生变化,都重新走一遍查询接口。

这时就可以定义这一组一对多的依赖,将相关标签页的key推入Store中定义的列表作为状态。使用观察者模式使那些存于列表中的Tab刷新。

相关推荐
Mike_jia12 分钟前
DBSyncer:开源数据同步中间件全景实战指南
前端
烛阴25 分钟前
从`new`关键字开始:精通C#类与对象
前端·c#
天若有情67330 分钟前
笑喷!乌鸦哥版demo函数掀桌怒怼主函数:难办?那就别办了!
java·前端·servlet
记得记得就15130 分钟前
【Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装】
前端·nginx·http
天蓝色的鱼鱼31 分钟前
mescroll老用户亲测z-paging:这些功能让我果断切换!
前端·uni-app
JarvanMo36 分钟前
适用于 iOS 开发者的 Flutter 3.38:Xcode 与 Swift 集成新技巧
前端
北极糊的狐1 小时前
Vue 中 vue-awesome-swiper的使用笔记(适配 Vue2/Vue3)
前端·javascript·vue.js
anyup1 小时前
🔥100+ 天,已全面支持鸿蒙!uView Pro 近期更新盘点及未来计划
前端·uni-app·harmonyos
2***57421 小时前
前端数据可视化应用
前端·信息可视化
DevUI团队1 小时前
Angular开发者必看:深度解析单元测试核心技巧与最佳实践
前端·javascript·angular.js