Observer (наблюдатель) — один из фундаментальных паттернов проектирования, обеспечивающий реактивное обновление данных и синхронизацию состояния между объектами. В контексте JavaScript и фреймворка Inferno паттерн используется для управления состоянием компонентов и эффективного обновления пользовательского интерфейса при изменении данных.
Паттерн Observer строится вокруг двух ключевых ролей:
Схема работы паттерна:
Такой подход позволяет создавать слабосвязанные компоненты, где изменение одного объекта автоматически отражается на всех заинтересованных частях приложения.
Inferno как высокопроизводительный фреймворк для построения UI поддерживает реактивное управление состоянием через обычные JavaScript-объекты. Observer можно реализовать с помощью простого класса для управления подписками.
Пример базовой реализации:
class Observable {
constructor(value) {
this.value = value;
this.subscribers = new Set();
}
subscribe(callback) {
this.subscribers.add(callback);
return () => this.subscribers.delete(callback);
}
setValue(newValue) {
if (this.value !== newValue) {
this.value = newValue;
this.notify();
}
}
notify() {
this.subscribers.forEach(callback => callback(this.value));
}
getValue() {
return this.value;
}
}
Особенности реализации:
Set для хранения подписчиков исключает
дублирование.subscribe возвращает функцию для отписки.notify автоматически вызывается при изменении
значения.Для связки Observable с компонентами Inferno удобно использовать
жизненный цикл компонентов. В функциональных
компонентах можно применять useEffect для подписки и
отписки:
import { useState, useEffect } from 'inferno-hooks';
function Counter({ observable }) {
const [count, setCount] = useState(observable.getValue());
useEffect(() => {
const unsubscribe = observable.subscribe(setCount);
return unsubscribe;
}, [observable]);
return (
<div>
<p>Счётчик: {count}</p>
<button onCl ick={() => observable.setValue(count + 1)}>Увеличить</button>
</div>
);
}
Ключевые моменты интеграции:
useState хранит локальное состояние компонента.useEffect подписывается на изменения
observable при монтировании и автоматически отписывается
при размонтировании.Пример вычисляемого значения:
class ComputedObservable {
constructor(observables, computeFn) {
this.value = computeFn(...observables.map(o => o.getValue()));
this.subscribers = new Set();
observables.forEach(o =>
o.subscribe(() => {
this.value = computeFn(...observables.map(obs => obs.getValue()));
this.notify();
})
);
}
subscribe(callback) {
this.subscribers.add(callback);
return () => this.subscribers.delete(callback);
}
notify() {
this.subscribers.forEach(cb => cb(this.value));
}
getValue() {
return this.value;
}
}
Observer паттерн в Inferno становится основой эффективного реактивного подхода, позволяя управлять состоянием приложения чисто и производительно, минимизируя лишние рендеры и повышая гибкость архитектуры.