@semennn

Как правильно реализовать подписку в паттерне Observer?

Ребята, подскажите:

есть примитивная реализация класса Observer (методы subscribe, publish).
и два класса: один издатель Main, другой наблюдатель Slave.
Как правильно реализовать паттерн - экземпляр класса Main подписывает слушателей или экземпляр Slave сам подписывается на события?
С первым все понятно:
class Main extends Observer {
.............
}

let main = new Main(args);
let slave = new Slave(args);
main.subscribe(slave.func.bind(slave));


то как реализовывается самостоятельная подписка на события main? или все используют подписку на стороне издателя?
  • Вопрос задан
  • 329 просмотров
Решения вопроса 1
edli007
@edli007
full stack, team lead
Тут есть несколько решений но чаще всего встречал решение похожее на ваше в примере, через функцию subscribe

Либо
main.events.on('.....', (e) => {
  .....
})
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
yurakostin
@yurakostin
Front-end developer
Фактически есть тот, кто издаёт новости и тот, кто хочет их получать.

Таким образом есть две сущности: Издатель и Подписчик.

Издатель извещает о том, что что-то произошло.
Подписчик реагирует на это происшествие.

Так у нас получается что-то такое:

Подписчик
methods:
+ отреагировать на событие

Издатель
props:
- подписчики

methods:
- оповестить подписчиков
+ добавить подписчика
+ удалить подписчика
+ издать новость

Если уйти от псевдокода, то получится следующее:

class Publisher {
    constructor() {
        this._subscribers = [];
        this._state = {};
    }

     get state() {
        return this._state;
    }

    set state(value) {
        this._state = Object.assign({}, this._state, value);
        // Неявный вызов, можно, наверное, сделать лучше
        this._notifySubscribers();
    }

    _notifySubscribers() {
        this._subscribers.forEach((subscriber) => subscriber.notify(this._state))
    }

    addSubscriber(subscriber) {
        this._subscribers.push(subscriber);
    }
}

class Subscriber {
    constructor(name) {
        this.name = name;
    }

    notify(state) {
        console.log(`${this.name}: i received a new data: `, state);
        console.log('\n\n')
    }
}

const publisher = new Publisher();
const subscriber1 = new Subscriber('John');
const subscriber2 = new Subscriber('Jane');
const subscriber3 = new Subscriber('Mary');

publisher.addSubscriber(subscriber1);
publisher.state = {a: 1};

publisher.addSubscriber(subscriber2);
publisher.state = {b: 2};

publisher.addSubscriber(subscriber3);
publisher.state = {c: 3};


Код рабочий.

Надеюсь, что я вас нигде не обманул и всё объяснил правильно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы