Observer pattern with two lists of observers
I have a class MyObserver that listens to changes in Notifier. Notifier extends Observable and notify its events with noti开发者_Python百科fyObservers(Object). The object passed as argument is always an instance of the same class. The problem is that each observer need to listen to diferent events. For example one observer needs to listen to state changed events and others to all types of events. How can I do this with observer pattern?
Thanks.
Use notifyObservers(Object arg) version and create some sort of "event type" object to stick in there. In your observing classes simply filter on the passed in event class.
public void update(Object observable, Object arg) {
if ( (MyEvent) arg.isEventX() ) { /* do stuff */ }
}
I think that the Java built-in implementation of the Observer Pattern is not suitable for your case.
In fact, the general Observer pattern is usable when just one Observable kind of events can arise. In the Observer Design Pattern, all the Observes get notified always.
So, in this case, you need to extend the general Observer pattern, by defining your own Observable interface, for example, this way:
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);
}
Then you can just implement this Observable interface with internal lists for each kind of event to notify. You can still use the Java built-in Observer interface if you wish.
This approach has the following benefits:
- You can flexibly add more kind of events without affecting the code of the Observers.
- You can register any observer to any event.
- You update just the Observers that are effectively interested in each event.
- You avoid "empty methods", "event type checking" and other tricks on the Observers side.
If you can change the design a bit:
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.
}
}
Usage:
MyObserver stateObserver = new MyStateChangeObserver();
MyObserver otherObserver = new MyOtherObserver();
notifier.notifyObservers(stateObserver);
notifier.notifyObservers(otherObserver);
You can test for a state change by doing the following in the Observable class:
public void update(Observable o, Object arg)
{
if(o.hasChanged())
{
// do something
}
}
The observers that listen to anything don't need this test. This is probably the easiest way if you only want to listen for state changes.
精彩评论