初学者观察者模式

2023-12-11 22:57:49 浏览数 (1)

观察者模式是一种广泛使用的行为设计模式。它允许对象订阅并接收关于它们正在观察的对象发生的事件的更新。

思考一个在线服装商店的例子。你想要一件特定的连帽衫,但目前缺货。你每天都会检查网站以查看是否有货。商店提供产品再次有货时的提醒,因此你订阅接收通知。这消除了手动检查商店的需求。

这类问题通常使用观察者模式解决。

观察者模式主要有两个角色:

  • 可观察者或发布者
  • 观察者或订阅者

在上面的例子中,可观察者是你正在寻找的产品,而你是观察者。

可观察者模式背后的关键概念是松耦合,可观察者和观察者不需要了解彼此的具体细节。在上面的例子中,你已经解耦了自己不必每天手动检查商店,商店也只在相关更改时通知你。

思维模型

以下是观察者模式的思维模型:

可观察者

  • 这是正在被观察的对象。
  • 它维护一个观察者列表。
  • 它提供订阅、取消订阅和通知观察者的方法。

观察者

  • 这是对可观察对象状态变化感兴趣的对象。
  • 它订阅可观察对象以接收更新。
  • 它有一个在可观察对象状态改变时被调用的更新方法。
  • 可以有多个观察者。

代码实现

让我们使用 TypeScript 类来实现这个。

首先,我们将创建一个名为Store的可观察者类,它具有以下接口,

代码语言:typescript复制
interface Observable {
  subscribe(o: Observer): void;
  unsubscribe(o: Observer): void;
  notify(): void;
}

可观察者类将有一个名为 message 的私有字符串变量和一个 setMessage 方法来更新产品可用性的状态。它还将有一个数组来维护观察者列表。最后,让我们添加 subscribe、unsubscribe 和 notify 方法。

以下是可观察者的完整实现,

代码语言:typescript复制
class Store implements Observable {
  private message: string = "";
  private observers: Array<Observer> = [];

  setMessage(message: string) {
    this.message = message;
    this.notify(); // 当消息状态改变时通知所有观察者
  }

  subscribe(o: Observer): void {
    this.observers.push(o);
  }

  unsubscribe(o: Observer): void {
    const index = this.observers.indexOf(o);
    this.observers.splice(index, 1);
  }

  notify(): void {
    for (const o of this.observers) {
      o.update(this.message); // 使用新消息调用观察者的 update 方法
    }
  }
}

现在,让我们创建一个名为User的观察者类,它具有以下接口,

代码语言:typescript复制
interface Observer {
  update(notice: string): void;
}

观察者类将是简单的,只有 update 方法。以下是观察者的完整实现,

代码语言:typescript复制
class User implements Observer {
  private observable: Observable;

  constructor(observable: Observable) {
    this.observable = observable;
    this.observable.subscribe(this); // 创建新的 User 对象时自动订阅
  }

  update(message: string): void {
    console.log(`Store update : ${message}`);
  }
}

现在,当我们使用 setMessage 函数更新商店消息时,它将通知类的所有观察者。

代码语言:typescript复制
const store = new Store();
const user = new User(store); // 创建后,它观察 store 类

// store.subscribe(user) // 订阅 observable 的另一种方式

store.setMessage("连帽衫现已上架"); // 这将调用 update 方法并在控制台记录消息
store.unsubscribe(user);
store.setMessage("秋季促销已经开始"); // 这条消息不会被记录

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞