dassimon
dassimon

Reputation: 141

Appropriate use of Event-Listener pattern

I appreciate this may not be a right/wrong type question, possibly more a stylistic thing but I often find myself pondering the use (overuse?) of custom Event and EventListener classes.

Frequently I have a class (often a GUI component) that needs to make other components aware of some change in it's state.

I could maintain a list of ChangeListeners (or some other already defined, general purpose listener type) and then call them on a state change, for example:

for (final ChangeListener cl : changeListeners)
    cl.stateChanged(new ChangeEvent(this));

then retrieve the value in the listener:

class SomeListener implements ChangeListener {
    @Override
    public void stateChanged(ChangeEvent e) {
        ((MyClass) e.getSource()).getSomeStateProperty();
        .
        .
        .
    }

However the cast to MyClass strikes me as bad practice as the listener class is now making an explicit assumption about the contents of that ChangeEvent which has not been explicitly declared as the ChangeEvent constructor takes type Object.

So I frequently find myself creating pairs of custom Event and EventListener classes/interfaces i.e.

public interface SomeThingChangeListener extends EventListener {
    /**
     * Invoked when the target of the listener has changed some thing.
     *
     * @param e a SomeThingChangeEvent object
     */
     void someThingChanged (SomeThingChangeEvent e);
} 

With a corresponding Event class that contains a reference to the pertinent change information (probably a reference to an interface or abstract class in the event constructor).

The thing that bothers me about this however is the large proliferation of these small connector classes/interfaces for all 'things' that might 'happen' that may only ever have one concrete implementation.

So I guess the question is; is it best just to use general purpose events/listeners wherever you can or to always make class/event specific events and listeners?

The main reason that I seem to create quite a lot of these is that it often occurs to me that the association between two (or more) classes tends to be fairly weak, they are often not really related to each other in any way but one may be interested in information/state created/modified by another but not care about the details of the source. I find the observer or event/listener pattern a good way to keep coupling between unrelated classes to a minimum.

Any thoughts?

Thanks in advance,
Simon.

Upvotes: 1

Views: 559

Answers (1)

Harmlezz
Harmlezz

Reputation: 8078

In my opinion defining specific types for each event, which makes up your domain model, is a good practice (one I do prefer / follow most of the times). Having as many event listeners as different event types may cause class pollution. On the other side, a generic listener approach leads to either determine the event type by sequences of instanceof or using the Visitor Pattern to dispatch events. The Visitor Pattern couples events to the listener. Perhaps a compromise between listeners capable of consuming more than one event (having change listener methods for related events) will reduce the number of different listeners by preserving event specific consuming, avoiding sequences of instanceof.

A proper solution depends on the concrete project and is always a tradeoff of many aspects.

Upvotes: 1

Related Questions