суббота, 12 января 2013 г.

Паттерны Ruby. Наблюдатель (Observer)

Шаблон Наблюдатель (Observer) применяется в сильно интегрированных системах, где каждая часть должна знать состояние всей системы, или большей ее части (например, если нужно показать график изменений какого-либо значения без жесткого указания связи в коде или работнику нужно оповестить об изменении зарплаты соответствующие отделы).
Диаграмма классов паттерна Наблюдатель (Observer)


Рассмотрим пример, когда платежная ведомость должна знать об изменении зарплаты сотрудника.
Приведем простейшую версию класса сотрудник:


Она никого ни о чем не уведомляет, эта версия просто представляет собой базовые поля объекта.

Теперь добавим простейшую реализацию слежения за изменением зарплаты - Employee будет принимать платежную ведомость и вызывать ее метод update при изменении зарплаты:

Недостатком данного кода является жесткая привязка объектов. Что будет если понадобится извещать больше одного слушателя? Нам придется лезть в код Employee и менять его, что, согласитесь, очень не правильно.

Обобщим решение, создав переменную, хранящую массив наблюдателей и реализовав методы по добавлению и удалению наблюдателей:


Так выглядит простейшая реализация паттерна с использованием модулей. Чтобы их использовать, достаточно в класс наблюдателя включить модуль Observer и реализовать метод update_from_observable(context). Context при этом является объектом наблюдаемого. В наблюдаемый объект нужно включить модуль Observable, добавить наблюдателей с помощью метода add_observer и вызывать метод notify_observers каждый раз, когда необходимо уведомить наблюдателей об изменениях.

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

Отправить комментарий