Шаблон наблюдателя с двумя списками наблюдателей
У меня есть класс MyObserver, который слушает изменения в Notifier. Notifier расширяет Observable и уведомляет о своих событиях с помощью notifyObservers (Object). Объект, передаваемый в качестве аргумента, всегда является экземпляром одного и того же класса. Проблема в том, что каждый наблюдатель должен прислушиваться к различным событиям. Например, один наблюдатель должен слушать изменения состояния событий, а другие - все типы событий. Как я могу сделать это с шаблоном наблюдателя?
Спасибо.
4 ответа:
Если вы можете немного изменить дизайн:
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);
Используйте notifyObservers(Object arg) version и создайте какой-то объект "типа события", чтобы вставить его туда. В ваших наблюдающих классах просто фильтруйте по переданному в событии классу.
public void update(Object observable, Object arg) { if ( (MyEvent) arg.isEventX() ) { /* do stuff */ } }
Я думаю, что встроенная в Java реализация шаблона Observer не подходит для вашего случая.
На самом деле, общая модель наблюдателя применима, когда может возникнуть только один наблюдаемый вид событий. В шаблоне проектирования наблюдателя все наблюдатели получают уведомление Всегда.Итак, в этом случае вам нужно расширить общую модель наблюдателя , определив свой собственный наблюдаемый интерфейс, например, таким образом:
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); }
Тогда вы можете просто реализуйте этот наблюдаемый интерфейс с внутренними списками для каждого типа событий для уведомления. Вы все еще можете использовать встроенный в Java интерфейс наблюдателя, если хотите.
Этот подход имеет следующие преимущества:
- вы можете гибко добавлять больше видов событий не затрагивая код самого Наблюдатели.
- вы можете зарегистрировать любого наблюдателя в любой событие.
- вы обновляете только наблюдателей которые эффективно заинтересованы в каждый событие.
- вы избегаете "пустых методов", "проверки типа события" и других трюки со стороны наблюдателей.
Вы можете проверить изменение состояния, выполнив следующие действия в классе Observable:
Наблюдатели, которые слушают что-либо, не нуждаются в этом тесте. Это, вероятно, самый простой способ, если вы хотите только слушать изменения состояния.public void update(Observable o, Object arg) { if(o.hasChanged()) { // do something } }