/** * * ПАТТЕРН НАБЛЮДАТЕЛЬ (почтальон) * Несколько наблюдателей (подписчиков) могут получать данные от одного субьекта (почтальона) * */ class Publisher { // субьект, получает и рассылает данные constructor() { this.observersList = []; // реестр наблюдателей (подписчиков) this.state = []; // хранит состояние Субьекта (т.е. хранит последние полученные данные) } subscribe(obj) { // подписка наблюдателя return this.observersList.push(obj); } unsubscribe(obj) { // отписка наблюдателя this.observersList = this.observersList.filter((item) => item !== obj); return this.observersList; } notifyObservers(...args) { // рассылка данных наблюдателям for (observer of this.observersList) { observer.update(this, this.state); } } setState (...args) { this.state = [...args]; } getState () { this.state.forEach((arg) => { console.log(arg); }); } } class Observer { constructor(publisher, observerName='DefaultObserverName') { // observerName нужен только для наглядности примера if (!publisher) { throw new Error('Не указан Publisher (субьект) при создании наблюдателя (Observer)'); } publisher.subscribe(this); // при создании наблюдателя автоматически добавляем его в ресстр субьекта this.observerName = observerName; } update(publisher, ...args) { // получаем данные от Субьекта (Publisher) и вызываем для них функцию-обработчик [...args].forEach((arg) => { this.updateHandler(arg); }); } updateHandler(arg) { // Обработка новых данных. console.log(this.observerName + ': ' + arg); } } let subject = new Publisher(), // создаем Субьекта observer = new Observer(subject, 'Наблюдатель 1'), // создаем наблюдателя за Субьектом observer2 = new Observer(subject, 'Наблюдатель 2'), // создаем наблюдателя за Субьектом observer3 = new Observer(subject, 'Наблюдатель 3'); // создаем наблюдателя за Субьектом subject.setState('foo'); // Сообщаем новые данные субьекту subject.notifyObservers(); // Рассылаем данные всем трем наблюдателям субьекта subject.unsubscribe(observer2); // Удаляем одного наблюдателя из трех из реестра наблюдателей subject.getState(); // Проверяем что за данные сейчас у субьекта subject.notifyObservers(); // Рассылаем данные оставшимся двум наблюдателям subject.setState(['BAR', 'fuck', 'man']); // Сообщаем новые данные субьекту subject.notifyObservers(); // Рассылаем данные оставшимся двум наблюдателям