Reputation: 17945
In many of the standard Java libraries (and most notably in AWT/Swing) you can find the following EventListener / Event pattern:
interface FooEventListener {
void fooDidBar(FooEvent e);
void fooDidBaz(FooEvent e);
void fooDidQux(FooEvent e);
}
And, in the FooEvent
, you further find
public class FooEvent {
static int FOO_DID_BAR = 1;
static int FOO_DID_BAZ = 2;
static int FOO_DID_QUX = 3;
// ...
public int getID(); // one of the above constants
}
This seems redundant. Why was this decision taken? What is the advantage of having this information both in the specific method called and in the event passed as an argument to that method?
Examples:
Upvotes: 0
Views: 80
Reputation: 17945
After some thought, I think I see additional advantages to double-encoding event subtypes (Bar
, Baz
, Qux
in the example), beyond its historical importance:
Having one callback-method per event subtype allows cleaner listener implementations, as no switch-like statements are needed to take different actions for each subtype. So far this is used in most event-handling code and is pretty evident.
Having a subtype-id (getId()
, which could be renamed to getType()
for non-legacy events) in the event objects themselves is relatively low-cost from an implementation perspective (define a bunch of constants and keep them in sync with the corresponding subtype methods); and when present allows interesting debugging strategies: the sequence of events fired by a particular model can then contain all the information needed to reconstruct all changes to the model. Essentially, it makes fooEvent.toString()
that much more detailed.
I further suspect that "fully self-contained event objects allow much easier debugging" is a strong reason for the historical double-encoding.
Upvotes: 0
Reputation: 5948
I think the reasons are:
1) All AWT/Swing events extend AWTEvent
and need to provide event id to its parent constructor. This is partly required by legacy AWT codebase and for event dispatching as mentioned by @MadProgrammer.
2) It is much cleaner design to implement one particular callback method in the listener instead of checking for event id constants in a single method. Actually in old days we would just delegate to private methods from a single event callback method based on event id.
3) This allowed the use of Adapter classes that help to only implement callback methods for only interested events.
Upvotes: 1