может ли наблюдатель наблюдать несколько наблюдаемых? - PullRequest
2 голосов
/ 28 января 2011

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

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

Примеры шаблонов наблюдателей, которые я видел, демонстрируют, что многие наблюдатели наблюдают за одной наблюдаемой, могу ли я (или должен ли я)сделать это наоборот?Что еще я должен делать?

Ответы [ 5 ]

4 голосов
/ 28 января 2011

Просто зарегистрируйте один экземпляр 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();

Также вам может потребоваться поиск шаблона Mediator .

Вот его довольно приятная реализация: SymfonyДиспетчер событий

3 голосов
/ 28 января 2011

Я думаю, что очень важно помнить, что шаблоны проектирования - это предложения, а не абсолюты.Если они могут быть изменены, чтобы лучше соответствовать вашим потребностям, то они должны.

И да, в этом случае это вполне можно сделать.Ваши наблюдатели просто должны зарегистрироваться более чем с одним наблюдаемым объектом.

Когда один из ваших наблюдаемых объектов уведомит своих наблюдателей, он просто зациклится на списке ссылок, чтобы сообщить им об обновлении.Это действительно не имеет значения, если эти ссылки используются совместно с другими наблюдаемыми объектами.

1 голос
/ 28 января 2011

Из GoF (раздел реализации шаблона Observer), " Наблюдение более чем за одним субъектом . В некоторых ситуациях может иметь смысл зависеть от наблюдателя от более чем одного субъекта. Например, электронная таблица может зависеть от более чем одного источника данных. В таких случаях необходимо расширить интерфейс обновления, чтобы наблюдатель знал, какой субъект отправляет уведомление. Субъект может просто передать себя в качестве параметра в операции обновления, тем самым давая знать наблюдателю какой предмет для изучения. "

Ответ от Mchl уже содержит пример. Я просто добавляю ссылку от GoF, что это не будет плохой практикой, если вам нужно это сделать.

1 голос
/ 28 января 2011

Я согласен с идеей, что 1 класс выполняет 1 основное задание.Если бы это был я, я бы создал интерфейс наблюдателя, создал бы несколько реализаций наблюдателя и управлял бы всеми этими наблюдателями с помощью некоторого класса ObserverManager.

Делая это таким образом, вы отделите все свои бизнес-задачи и предоставитеболее тонкий уровень детализации для тестирования.

Если «изменения многих других операций» не могут быть охарактеризованы как тот же самый вид наблюдаемого «изменения».В этот момент единственный наблюдатель имеет смысл.

0 голосов
/ 28 января 2011

Это, безусловно, выполнимо.Все, что вам нужно сделать, - это добавить добавить в функцию / метод обервера параметр, указывающий на наблюдаемое.

...