понедельник, 9 ноября 2020 г.

A programmer: JavaScript #20. Pattern "Observer"

В общих чертах петтерн "observer" (обозреватель, наблюдатель) предполагает, что есть некий объект, который меняет своё состояние и оповещает об этом тех, кто подписан на уведомления (subscribers). Применительно к React'у это более, чем актуально, поскольку при изменении состояния (данных), компоненты должны перерисовываться, а значит, должны следить за изменениями сообветствующих данных.

При этом компоненты, которые себя перерисовывают, получают данные, зависят от них, но state, который хранит состояние, не должен зависеть от них - то есть он не должен сам вызывать метод перерисовки, находящийся в компонентах. Тогда как компоненты узнают, что state изменился?

А вот как: 

С одной стороны, файл, где происходит отрисовка компонентов (допустим, index.js) вызывает rerender() и передает туда state, который предварительно импортирует:

rerender(state);

То есть index.js зависит от state'а, как и положено.

Но index.js также вызывает метод subscribe и передает туда вызов свой rerender():

subscribe(rerender);

Теперь rerender() может быть вызван прямо в state, при этом state от него не зависит, а только использует реализацию.

С другой стороны, при изменении state вызывает callSubscriber(), но его реализацию он получает в распоряжение из метода subscribe():

// некоторые изменения данных

callSubscriber();

В самом state он описывается приблизительно так:

export const subscribe = (observer) => {
     rerender = observer;
}

То есть теперь callSubscriber(), вызываемый в state, - это тот самый rerender(), который реализован в index.js.

Следовательно, теперь при любом изменениии state, он вызывает метод перерисовки, который он получил через subscribе. Это означает, что state по-преженему не зависит от UI, потому что ему всё равно, как реализована перерисовка - он её только вызывает, но не импортирует.

P.S.: Обычно паттерн "observer" объясняют на примере Java. В некотором смысле оно понятнее, потому что там есть интерфейсы как отдельные сущности. Но вот мне помогло объяснение в исполнении Димыча.

Комментариев нет: