Шаблон наблюдателя с двумя списками наблюдателей - PullRequest
4 голосов
/ 29 июня 2011

У меня есть класс MyObserver, который прослушивает изменения в Notifier. Notifier расширяет Observable и уведомляет его события с помощью notifyObservers (Object). Объект, переданный в качестве аргумента, всегда является экземпляром одного и того же класса. Проблема в том, что каждый наблюдатель должен слушать разные события. Например, один наблюдатель должен слушать изменения состояния, а другие - все типы событий. Как я могу сделать это с помощью шаблона наблюдателя?

Спасибо.

Ответы [ 4 ]

5 голосов
/ 29 июня 2011

Мне кажется, что встроенная в Java реализация Observer Pattern не подходит для вашего случая.

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

Итак, в этом случае вам нужно расширить общий шаблон Observer , определив свой собственный интерфейс Observable, например, так:

public enum EventKind {
   EVENT_A, EVENT_B, EVENT_C;
}

public interface Observable {
   public void registerObserver(EventKind eventKind);
   public void unregisterObserver(EventKind eventKind);
   public void notifyObservers(EventKind eventKind);
}

Тогда вы можете просто реализовать этот интерфейс Observable с внутренними списками для каждого типа события для уведомления. Вы все еще можете использовать встроенный интерфейс Java Observer, если хотите.

Этот подход имеет следующие преимущества:

  1. Вы можете гибко добавлять больше видов событий не влияя на код Наблюдатели.
  2. Вы можете зарегистрировать любого наблюдателя на любой событие.
  3. Вы обновляете просто Наблюдатели которые эффективно заинтересованы в каждое событие.
  4. Вы избегаете «пустых методов», «проверки типов событий» и других трюки на стороне наблюдателей.
5 голосов
/ 29 июня 2011

Используйте notifyObservers (Object arg) version и создайте некоторый объект типа "событие", чтобы придерживаться там. В ваших классах наблюдения просто отфильтруйте переданный в классе события.

public void update(Object observable, Object arg) {
    if ( (MyEvent) arg.isEventX() ) { /* do stuff */ }
}
3 голосов
/ 29 июня 2011

Если вы можете немного изменить дизайн:

interface MyObserver {
    public void stateChangeEvent();
    public void otherEvent();
}

class MyObserverAdapter implements MyObserver {
    public void stateChangeEvent() {
         // some default implementation or no implementation.
    }

    public void otherEvent() {
         // some default implementation or no implementation.
    }
}

class MyStateChangeObserver extends MyObserverAdapter {
    public void stateChangeEvent() {
         // implement behavior specific to this class.
    }
}

class MyOtherObserver extends MyObserverAdapter {
    public void otherEvent() {
         // implement behavior specific to this class.
    }
}

Использование:

MyObserver stateObserver = new MyStateChangeObserver();
MyObserver otherObserver = new MyOtherObserver();
notifier.notifyObservers(stateObserver);
notifier.notifyObservers(otherObserver);
0 голосов
/ 29 июня 2011

Вы можете проверить изменение состояния, выполнив следующие действия в классе Observable:

public void update(Observable o, Object arg)
{
    if(o.hasChanged())
    {
        // do something
    }
}

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

...