пытаясь найти пример этого, возможно, что я не пойду правильным путем, или что мой разум более упростил концепцию шаблона наблюдателя.
Я хочу создать класс, который управляет сообщениями из веб-службы, и я хочу, чтобы этот класс контролировал изменения многих других операций.
Образцы шаблонов наблюдателей, которые я видел, показывают, что многие наблюдатели наблюдают за одним наблюдаемым, могу ли я (или должен ли я) сделать это наоборот? Что еще я должен делать?
Просто зарегистрируйте один экземпляр Observer во многих экземплярах Oservable.
Вероятно, вам захочется передать Observable экземпляр Observer при любых Observable-обновлениях, чтобы Observer знал, какой конкретный объект обновил его.
Тривиальный пример:
interface Observer { public update(Observable $observable); } class Observable() { private $observers = array(); public function register(Observer $observer) { $this->observers[] = $observer; } public function update() { foreach($observers as $observer) { $observer->update($this); } } } $observer = new ObserverImplementation(); $observable1->register($observer); $observable2->register($observer); $observable1->update(); $observable2->update();
Также вы можете найти шаблон посредника .
Вот довольно хорошая реализация: Sympony Event Dispatcher
Я думаю, что очень важно помнить, что шаблоны дизайна – это предложения, а не абсолюты. Если они могут быть изменены, чтобы лучше соответствовать вашим потребностям, тогда они должны.
И да, в этом случае это может быть определенно сделано. Вашим наблюдателям просто нужно будет зарегистрировать более одного наблюдаемого объекта.
Когда один из ваших наблюдаемых объектов уведомит об этом наблюдатели, он просто зациклится на списке ссылок, чтобы сообщить им обновить. Не имеет значения, разделены ли эти ссылки с другими наблюдаемыми объектами.
From GoF (раздел реализации шаблона Observer), « Наблюдение за несколькими субъектами . В некоторых ситуациях может быть смысл, если наблюдатель будет зависеть от более чем одного субъекта. Например, электронная таблица может зависеть от нескольких источников данных. В таких случаях необходимо расширить интерфейс обновления, чтобы наблюдатель знал, какой объект отправляет уведомление. Субъект может просто передать себя в качестве параметра в операции обновления, тем самым позволяя наблюдателю узнать, какой предмет будет исследован ».
Ответ от Mchl уже содержит пример. Я просто добавляю ссылку из GoF, что это не будет плохой практикой, если вам нужно это сделать.
Это, безусловно, выполнимо. Все, что вам нужно сделать, это передать добавление параметра функции / метода oberver, который указывает на наблюдаемый.
Я соглашаюсь с тем, что 1 класс выполняет 1 основную задачу. Если бы это был я, я бы построил интерфейс наблюдателя, создавал несколько реализаций наблюдателей и управлял всеми этими наблюдателями некоторым классом ObserverManager.
Выполнение этого способа позволит отделить все ваши деловые проблемы и даст более тонкий уровень детализации для тестирования.
Если «изменения многих других операций» можно охарактеризовать как одно и то же наблюдаемое «изменение». В этот момент единственный наблюдатель имеет смысл.