Расскажите о шаблоне наблюдателя и шаблоне публикации-подписки.

Шаблоны проектирования

Я видел много сообщений в блогах о режиме наблюдателя и режиме публикации-подписки в Интернете и обнаружил, что многие люди думают, что режим наблюдателя — это режим публикации-подписки. различия между режимом наблюдателя и режимом публикации-подписки. , давайте поговорим о моем понимании режима наблюдателя и режима публикации-подписки "PS: приветствую исправления от всех богов".

Шаблон наблюдателя (наблюдатель)

Шаблон наблюдателя относится к объекту (Subject), поддерживающему ряд объектов, которые зависят от него (Observer), и объект Subject уведомляет ряд объектов Observer об обновлении при изменении соответствующего состояния.

В шаблоне наблюдателя у объекта Subject есть методы для добавления, удаления, уведомления ряда наблюдателей и т. д., а у объекта наблюдателя есть методы обновления и т. д.

После того, как объект Subject добавляет ряд объектов Observer, объект Subject поддерживает серию объектов Observer, а объект Subject уведомляет ряд объектов Observer об обновлении при изменении соответствующего состояния.

// Subject 对象
function Subject(){
  this.observers = [];
}
Subject.prototype = {
  add(observer){  // 添加
    this.observers.push(observer);
  },
  notify(){  // 通知
    var observers = this.observers;
    for(var i = 0;i < observers.length;i++){
      observers[i].update();
    }
  },
  remove(observer){  // 删除
    var observers = this.observers;
    for(var i = 0;i < observers.length;i++){
      if(observers[i] === observer){
        observers.splice(i,1);
      }
    }
  },
}

// Observer 对象
function Observer(name){
  this.name = name;
}
Observer.prototype = {
  update(){  // 更新
    console.log('my name is '+this.name);
  }
}

var sub = new Subject();
var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2');
sub.add(obs1);
sub.add(obs2);
sub.notify();  //my name is ttsy1、my name is ttsy2

В приведенном выше коде мы создаем объект Subject и два объекта Observer.При изменении соответствующего состояния два объекта Observer уведомляются с помощью метода уведомления объекта Subject, а два объекта Observer обновляются с помощью метода обновления.

После добавления ряда объектов Observer к объекту Subject вы также можете удалить зависимость объекта Observer от него с помощью метода удаления.

var sub = new Subject();
var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2');
sub.add(obs1);
sub.add(obs2);
sub.remove(obs2);
sub.notify();  //my name is ttsy1

Модель публикации-подписки (издатель и подписчик)

Режим публикации-подписки означает, что объект, который хочет получать уведомления (Подписчик), подписывается на тему через специальное событие, основанное на теме, а объект, который публикует событие (Издатель), уведомляет каждый объект-подписчик, который подписывается на тему, путем публикация тематического события.

const pubSub = {
  list:{},
  subscribe(key,fn){  // 订阅
    if (!this.list[key]) {
      this.list[key] = [];
    }
    this.list[key].push(fn);
  },
  publish(){  // 发布
    const arg = arguments;
    const key = Array.prototype.shift.call(arg);
    const fns = this.list[key];

    if(!fns || fns.length<=0) return false;

    for(var i=0,len=fns.length;i<len;i++){
      fns[i].apply(this, arg);
    }
  },
  unSubscribe(key) {  // 取消订阅
    delete this.list[key];
  }
};

// 进行订阅
pubSub.subscribe('name', (name) => {
  console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
  console.log('your sex is ' + sex);
});
// 进行发布
pubSub.publish('name', 'ttsy1');  // your name is ttsy1
pubSub.publish('sex', 'male');  // your sex is male

Подписка на приведенный выше код основана на имени и темах пола для настройки события, публикация осуществляется через темы имени и пола, и передаются параметры пользовательского события, и, наконец, запускается пользовательское событие конкретной темы. .

Подписки на определенную тему можно отменить с помощью метода unSubscribe.

pubSub.subscribe('name', (name) => {
  console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
  console.log('your sex is ' + sex);
});
pubSub.unSubscribe('name');
pubSub.publish('name', 'ttsy1');  // 这个主题被取消订阅了
pubSub.publish('sex', 'male');  // your sex is male

Шаблон наблюдателя против шаблона публикации-подписки

И шаблон наблюдателя, и шаблон публикации-подписки определяют зависимость «один ко многим», и при изменении соответствующего состояния выполняется соответствующее обновление.

Разница заключается в том, что в режиме наблюдателя ряд объектов Observer, которые зависят от объекта Subject, могут выполнять один и тот же конкретный метод обновления только после получения уведомления, а в режиме публикации-подписки вы можете выполнять различные настройки на основе разных тем. событие. Условно говоря, режим публикации-подписки более гибкий и изменчивый, чем режим наблюдателя.

На мой взгляд, паттерн наблюдатель и паттерн публикация-подписка имеют по сути одну и ту же идею, а паттерн публикация-подписка можно рассматривать как расширенную версию паттерна наблюдатель.

Шаблон проектирования — это всего лишь идея. Определенный шаблон проектирования можно реализовать разными способами. Каждая реализация имеет свои преимущества и недостатки. Конкретные методы реализации должны основываться на различных бизнес-сценариях. Вышеизложенное является некоторыми из моих пониманий после изучения шаблона наблюдателя и шаблона публикации-подписки, пожалуйста, поправьте меня.