返回

从TS接口来理解观察者和发布订阅者设计模式

前端

观察者模式

观察者模式是一种设计模式,用于解决一对多的消息通信问题。在该模式中,观察者对象订阅可观察对象的事件,当可观察对象的状态发生变化时,可观察对象将通知所有订阅它的观察者。

在TypeScript中实现观察者模式

在TypeScript中实现观察者模式非常简单,首先我们需要定义一个接口来表示可观察对象:

interface Observable {
  addObserver(observer: Observer): void;
  removeObserver(observer: Observer): void;
  notifyObservers(): void;
}

然后,我们需要定义一个接口来表示观察者:

interface Observer {
  update(observable: Observable): void;
}

接下来,我们需要创建一个可观察对象的类,该类将实现Observable接口:

class ConcreteObservable implements Observable {
  private observers: Observer[] = [];

  addObserver(observer: Observer): void {
    this.observers.push(observer);
  }

  removeObserver(observer: Observer): void {
    const index = this.observers.indexOf(observer);
    if (index !== -1) {
      this.observers.splice(index, 1);
    }
  }

  notifyObservers(): void {
    for (const observer of this.observers) {
      observer.update(this);
    }
  }
}

最后,我们需要创建一个观察者的类,该类将实现Observer接口:

class ConcreteObserver implements Observer {
  update(observable: Observable): void {
    console.log(`Observer ${this.id} received a notification from ${observable}`);
  }
}

现在,我们可以使用这些类来实现观察者模式:

const observable = new ConcreteObservable();
const observer1 = new ConcreteObserver();
const observer2 = new ConcreteObserver();

observable.addObserver(observer1);
observable.addObserver(observer2);

observable.notifyObservers();

// Output:
// Observer 1 received a notification from ConcreteObservable
// Observer 2 received a notification from ConcreteObservable

发布订阅者模式

发布订阅者模式是一种设计模式,用于解决一对多的消息通信问题。在该模式中,发布者对象将消息发布到主题,订阅者对象订阅主题,当主题收到消息时,主题将通知所有订阅它的订阅者。

在TypeScript中实现发布订阅者模式

在TypeScript中实现发布订阅者模式也非常简单,首先我们需要定义一个接口来表示主题:

interface Subject {
  addSubscriber(subscriber: Subscriber): void;
  removeSubscriber(subscriber: Subscriber): void;
  notifySubscribers(): void;
}

然后,我们需要定义一个接口来表示订阅者:

interface Subscriber {
  update(subject: Subject): void;
}

接下来,我们需要创建一个主题的类,该类将实现Subject接口:

class ConcreteSubject implements Subject {
  private subscribers: Subscriber[] = [];

  addSubscriber(subscriber: Subscriber): void {
    this.subscribers.push(subscriber);
  }

  removeSubscriber(subscriber: Subscriber): void {
    const index = this.subscribers.indexOf(subscriber);
    if (index !== -1) {
      this.subscribers.splice(index, 1);
    }
  }

  notifySubscribers(): void {
    for (const subscriber of this.subscribers) {
      subscriber.update(this);
    }
  }
}

最后,我们需要创建一个订阅者的类,该类将实现Subscriber接口:

class ConcreteSubscriber implements Subscriber {
  update(subject: Subject): void {
    console.log(`Subscriber ${this.id} received a notification from ${subject}`);
  }
}

现在,我们可以使用这些类来实现发布订阅者模式:

const subject = new ConcreteSubject();
const subscriber1 = new ConcreteSubscriber();
const subscriber2 = new ConcreteSubscriber();

subject.addSubscriber(subscriber1);
subject.addSubscriber(subscriber2);

subject.notifySubscribers();

// Output:
// Subscriber 1 received a notification from ConcreteSubject
// Subscriber 2 received a notification from ConcreteSubject

比较观察者模式和发布订阅者模式

观察者模式和发布订阅者模式都是设计模式,用于解决一对多的消息通信问题。但是,这两种模式之间存在一些关键区别:

  • 在观察者模式中,可观察对象直接通知其观察者。而在发布订阅者模式中,主题将消息发布到主题,然后由主题通知其订阅者。
  • 在观察者模式中,观察者可以订阅多个可观察对象。而在发布订阅者模式中,订阅者只能订阅一个主题。
  • 在观察者模式中,可观察对象可以有多个观察者。而在发布订阅者模式中,主题可以有多个订阅者。

何时使用观察者模式和发布订阅者模式

观察者模式和发布订阅者模式都非常适合构建复杂的、可扩展的应用程序。但是,在某些情况下,一种模式可能比另一种模式更合适。

  • 如果您需要一对多的消息通信,并且希望观察者能够订阅多个可观察对象,那么观察者模式是更好的选择。
  • 如果您需要一对多的消息通信,并且希望订阅者只能订阅一个主题,那么发布订阅者模式是更好的选择。

结语

观察者模式和发布订阅者模式都是非常有用的设计模式。通过理解这两种模式,您可以构建更复杂、更可扩展的应用程序。