用JavaScript实现观察者模式

发布于:2025-02-10 ⋅ 阅读:(77) ⋅ 点赞:(0)
  1. 观察者模式定义:是一种行为设计模式,定义了一对多的依赖关系,主题对象状态变化时会通知所有观察者对象,使其自动更新。
  2. JavaScript 实现示例
    • 主题类(Subject):维护观察者数组,提供添加(addObserver)、移除(removeObserver)和通知(notifyObservers)观察者的方法。
    • 观察者类(Observer):定义update方法,在接收到通知时被调用。
    • 使用示例:创建SubjectObserver实例,添加观察者,通知观察者,移除观察者后再次通知,展示了观察者模式的基本流程。
  3. 优缺点
    • 优点:解耦观察者和被观察者;支持运行时动态添加或移除观察者;实现广播通信;是事件驱动架构的基础;可支持多种观察者。
    • 缺点:大量观察者时通知可能导致性能下降;存在循环依赖风险;缺乏变化细节,增加实现复杂性。
  4. 实际应用场景
    • GUI 事件监听:如 Web 开发中的 DOM 事件监听,按钮点击等事件处理。
    • 数据模型与视图同步:在 MVC 架构及 Vue.js、React 等框架中,实现数据模型变化时视图自动更新。
    • 发布 - 订阅系统:消息中间件(如 Kafka、RabbitMQ)和社交媒体平台采用该机制,发布者发布消息,订阅者接收通知处理。
    • 金融系统监控:股票市场监控系统中,投资者作为观察者订阅股票,股价变动时接收通知决策。
    • 缓存系统的失效通知:分布式系统中,缓存数据失效时通知相关系统或服务更新或重新加载数据。

 示例:

  1. 简单的事件发布 - 订阅系统
// 定义一个主题类(Subject)
class Subject {
  constructor() {
    this.observers = [];
  }
  // 添加观察者
  addObserver(observer) {
    this.observers.push(observer);
  }
  // 移除观察者
  removeObserver(observer) {
    const index = this.observers.indexOf(observer);
    if (index > -1) {
      this.observers.splice(index, 1);
    }
  }
  // 通知所有观察者
  notifyObservers(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}
// 定义一个观察者类(Observer)
class Observer {
  constructor(name) {
    this.name = name;
  }
  // 更新方法,在接收到通知时调用
  update(data) {
    console.log(`${this.name} received data: ${data}`);
  }
}
// 使用示例
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.addObserver(observer1);
subject.addObserver(observer2);
// 通知观察者
subject.notifyObservers('Hello Observers!');
// 移除一个观察者
subject.removeObserver(observer1);
// 再次通知观察者(此时只通知 observer2)
subject.notifyObservers('Hello Remaining Observer!');

在这个示例中,Publisher类充当主题角色,subscribeunsubscribepublish方法分别用于管理订阅者、取消订阅和发布事件通知订阅者。 

 

2. 模拟游戏角色状态变化通知 

// 游戏角色类(被观察者)
class GameCharacter {
    constructor(name) {
        this.name = name;
        this.health = 100;
        this.observers = [];
    }
    // 添加观察者
    addObserver(observer) {
        this.observers.push(observer);
    }
    // 移除观察者
    removeObserver(observer) {
        const index = this.observers.indexOf(observer);
        if (index > -1) {
            this.observers.splice(index, 1);
        }
    }
    // 通知观察者
    notifyObservers() {
        this.observers.forEach(observer => observer.update(this.name, this.health));
    }
    // 受到伤害方法
    takeDamage(damage) {
        this.health -= damage;
        console.log(`${this.name} 受到 ${damage} 点伤害,剩余生命值: ${this.health}`);
        this.notifyObservers();
    }
}

// 观察者类
class CharacterObserver {
    constructor(name) {
        this.name = name;
    }
    // 更新方法
    update(characterName, health) {
        console.log(`${this.name} 观察到 ${characterName} 的生命值变为: ${health}`);
    }
}

// 使用示例
const character = new GameCharacter('战士');
const observer1 = new CharacterObserver('玩家1');
const observer2 = new CharacterObserver('玩家2');
character.addObserver(observer1);
character.addObserver(observer2);
character.takeDamage(20);
character.removeObserver(observer1);
character.takeDamage(10);

该示例中,GameCharacter类表示游戏角色,当角色受到伤害时会通知所有观察者,展示了观察者模式在游戏开发中角色状态监控方面的应用。 


网站公告

今日签到

点亮在社区的每一天
去签到