Шаблон проектирования Наблюдатель - это популярный шаблон проектирования ПО широко используемый в разработке JavaScript-приложений . Экземпляр объекта ( Subject ) содержит коллекцию объектов-наблюдателей ( Observers ), которые он уведомляет, когда наступает определенное событие. Как бы сложно и непонятно это не звуч...

Шаблон проектирования наблюдатель в JavaScript

Шаблон проектирования Наблюдатель - это популярный шаблон проектирования ПО широко используемый в разработке JavaScript-приложений. Экземпляр объекта (Subject) содержит коллекцию объектов-наблюдателей (Observers), которые он уведомляет, когда наступает определенное событие. Как бы сложно и непонятно это не звучало бы, в основе достаточно простой механизм.

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

Вот как это все буде выглядеть в коде:

// определяем класс Subject
class Subject {
  
  constructor() {
    // массив объектов наблюдателей
    this.observers = [];
  }

  // добавляем объект-наблюдатель в массив
  subscribe(f) {
    this.observers.push(f);
  }

  // а здесь удаляем объект наблюдатель из массива
  // отфильтровывая значения
  unsubscribe(f) {
    this.observers = this.observers.filter(subscriber => subscriber !== f);
  }

  // вызываем каждый объект наблюдатель, передавая ему данные
  notify(data) {
    this.observers.forEach(observer => observer(data));
  }

}

Используем во так:

Файл разметки:

<input type="text" class="js-input" placeholder="type something here">
<button class="js-subscribe-p1">Подписаться</button>
<button class="js-unsubscribe-p1">Отписаться</button>
<p class="js-p1"></p>
<button class="js-subscribe-p2">Подписаться</button>
<button class="js-unsubscribe-p2">Отписаться</button>
<p class="js-p2"></p>
<button class="js-subscribe-p3">Подписаться</button>
<button class="js-unsubscribe-p3">Отписаться</button>
<p class="js-p3"></p>

Файл JavaScript

// ссылки на DOM
const input = document.querySelector('.js-input');
const p1 = document.querySelector('.js-p1');
const p2 = document.querySelector('.js-p2');
const p3 = document.querySelector('.js-p3');


// объекты наблюдатели
const updateP1 = text => p1.textContent = text;
const updateP2 = text => p2.textContent = text;
const updateP3 = text => p3.textContent = text;

// создаем класса Объекта Наблюдения
const subject = new Subject();

// добавляем наши действия в список наблюдателей
subject.subscribe(updateP1);
subject.subscribe(updateP2);
subject.subscribe(updateP3);

// при вводе текста в поле ввода, оповещаем всех наблюдателей о событии
input.addEventListener('keyup', e => {
  subject.notify(e.target.value);
});