Сайт вебмастера

Шаблон Observer (Наблюдатель)

02-11-2019Время чтения ~ 2 мин.PHP/ООП 6569

Поведенческий шаблон Наблюдатель реализует механизм, с момощью которого один класс может уведомлять другие о своём изменении. Практическая реализация кода может быть разной, но в PHP уже существуют готовые стандартные интерфейсы SplSubject, SplObjectStorage и SplObserver, на которых и принято реализовывать паттерн Observer.

Стоит отметить, что сам по себе этот шаблон родом из «больших» языков. Я уже рассказывал о его реализации для Java, где класс Модели отправляет уведомления о своём изменении всем своим «слушателям».

Исходный код вы найдёте на гитхабе. Рассмотрим его подробней.

Класс Наблюдатель (Observable) реализует интерфейс SplSubject. В этом классе хранятся «слушатели» — объекты стандартного класса SplObjectStorage. С помощью метода attach() добавляется новый «слушатель». Удалить его можно с помощью detach().

Также есть метод notify() которые «отправляет» уведомление об изменениях в классе «наблюдателя» всем своим «слушателям».

Каждый слушатель реализует стандартный интерфейс SplObserver и должен содержать метод update(). Собственно этот метод и используется в качестве «события».

Использование паттерна происходит по такой схеме. Вначале инстанцируется основной класс (Наблюдатель), после классы «слушателей», которые нужно зарегистрировать у Наблюдателя. Дальше, как только Наблюдателю нужно отправить уведомление вызывается метод notify(), который в свою очередь выполнит методы update() подчинённых классов.

В «больших» языках шаблон Observer имеет практический смысл, поскольку программы работают в событийной среде ОС. Например когда нажимается кнопка мыши, то Windows генерирует событие WM_LBUTTONDOWN, которое может перехватить программа. После этого программа всё также работает и функция для обработки нажатия кнопки просто ждёт когда придёт новое событие от операционной системы.

PHP — функциональный язык, где нет места событийности, поэтому шаблон Observer нужно рассматривать в более примитивной форме: по сути это просто вызов методов из «родительского» класса, где задача сводится только к тому, указать классы слушателей и вызвать какой-то предопределённый метод.

Похожие записи