Skip to content

Instantly share code, notes, and snippets.

@maplemap
Forked from DmitriiNazimov/pattern-observer.js
Created July 19, 2020 09:34
Show Gist options
  • Save maplemap/88f100ef5b7b761b82143452377e7945 to your computer and use it in GitHub Desktop.
Save maplemap/88f100ef5b7b761b82143452377e7945 to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн НАБЛЮДАТЕЛЬ (observer)] #ООП #js #ES6 #Паттерны
/**
*
* ПАТТЕРН НАБЛЮДАТЕЛЬ (почтальон)
* Несколько наблюдателей (подписчиков) могут получать данные от одного субьекта (почтальона)
*
*/
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(); // Рассылаем данные оставшимся двум наблюдателям
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment