【观察者模式】和【发布订阅】的区别

2022-07-13  本文已影响0人  青城墨阕

参考:https://juejin.cn/post/6978728619782701087

// 被观察者对象
class Subject {
    constructor() {
        this.observerList = [];
    }
  
    on(observer) {
        this.observerList.push(observer);
    }
  
    off(observer) {
        this.observerList = this.observerList.filter(o => o !== observer);
    }
  
    emit(message) {
        this.observerList.forEach(o => o.notified(message));
    }
}

// 观察者
class Observer {
    constructor(name, subject) {
      this.name = name;
      if (subject) {
        subject.on(this);
      }
    }
  
    notified(message) {
      console.log(this.name, ' got message:', message);
    }
}

const subject = new Subject();
const observerA = new Observer('observerA', subject);
const observerB = new Observer('observerB');
subject.on(observerB);
subject.emit('Hello from subject');

subject.off(observerA);
subject.emit('Hello again');
// 发布订阅中心
class PubSub {
    constructor() {
        this.messages = {};
        this.listeners = {};
    }
    publish(type, content) {
        const existContent = this.messages[type];
        if (!existContent) {
            this.messages[type] = [];
        }
        this.messages[type].push(content);
    }
    subscribe(type, cb) {
        const existListener = this.listeners[type];
        if (!existListener) {
            this.listeners[type] = [];
        }
        this.listeners[type].push(cb);
    }
    notify(type) {
        const messages = this.messages[type];
        const subscribers = this.listeners[type] || [];
        subscribers.forEach((cb, index) => cb(messages));
    }
}

// 发布者
class Publisher {
    constructor(name, context) {
      this.name = name;
      this.context = context;
    }
    publish(type, content) {
      this.context.publish(type, content);
    }
}

// 订阅者
class Subscriber {
    constructor(name, context) {
      this.name = name;
      this.context = context;
    }
    subscribe(type, cb) {
      this.context.subscribe(type, cb);
    }
}


// 使用示例
const TYPE_A = 'music';
const TYPE_B = 'movie';
const TYPE_C = 'novel';

const pubsub = new PubSub();

const publisherA = new Publisher('publisherA', pubsub);
publisherA.publish(TYPE_A, 'we are young');
publisherA.publish(TYPE_B, 'the silicon valley');
const publisherB = new Publisher('publisherB', pubsub);
publisherB.publish(TYPE_A, 'stronger');
const publisherC = new Publisher('publisherC', pubsub);
publisherC.publish(TYPE_C, 'a brief history of time');


const subscriberA = new Subscriber('subscriberA', pubsub);
subscriberA.subscribe(TYPE_A, res => {
  console.log('subscriberA received', res)
});
const subscriberB = new Subscriber('subscriberB', pubsub);
subscriberB.subscribe(TYPE_C, res => {
  console.log('subscriberB received', res)
});
const subscriberC = new Subscriber('subscriberC', pubsub);
subscriberC.subscribe(TYPE_B, res => {
  console.log('subscriberC received', res)
});

pubsub.notify(TYPE_A);
pubsub.notify(TYPE_B);
pubsub.notify(TYPE_C);
上一篇下一篇

猜你喜欢

热点阅读