Thursday, October 16, 2008

Are you listening?

Did you know that the Eclipse SDK alone has over 250 different listener interfaces? In the following screenshot, look at the size of the scrollbar slider!



This is only the tip of the iceberg - corresponding to all these listener interfaces, there are about 250 different Event classes. This is so that later on, additional event data can be added without breaking binary API compatibility by passing a dedicated event object to the listener. (Remember that where we forgot to use event objects, we ended up with warts like IPerspectiveListener4.)

To top it off, there are probably about 500 methods for adding and removing all these kinds of listeners. addLaunchLabelChangedListener/removeLaunchLabelChangedListener, addLocalSiteChangedListener/removeLocalSiteChangedListener, addLogEntryListener/removeLogEntryListener and so on.

In the end, when you think about it at a more abstract level, there are only a couple of possible changes that can happen in a program. A value can change, from an old value to a new value. A set can change, by adding or removing elements. A list can change, by adding elements at a certain index, removing elements at an index, or moving or replacing elements.

How about we use only three listener interfaces, IValueChangeListener, ISetChangeListener, and IListChangeListener? Or we settle on something that looks like EMF's notification API. We might need pre- and post-notifications, and maybe also changes to maps, so the resulting number of listener interfaces might be closer to ten. Definitely not 500 - and I only looked at the base Eclipse SDK...

What do you think? Can we make the Eclipse API more consistent and uniform in this way? Do you agree that all these domain-specific listener interfaces, each with a corresponding event class, and add/remove methods, are a source of accidental complexity, and settling on a small number of generic listener APIs can reduce code bloat?

6 comments:

Jilles said...

Yes fully agree that this is code bloat. Posted something on using generics to improve on this a long time ago: http://www.jillesvangurp.com/2005/10/26/late-to-generics/

Not perfect of course and probably with closures, it could be a lot cleaner still.

Max said...

Please no - without the specific types it becomes impossible to find example implementations of your specific listener plus you loose the ability to have typesafe input parameters.

Max said...

p.s. using Generics goes part of the way but can still result in too generic types/methods.

lokine said...

Modeling IWorkbenchPage as an Eobject and exposing active perspective or views as reference could permit to use the workbenchpage as notifier.... and use an adapter and its notifyChange method instead of hundreds of listeners.Maybe your e4 project of modelled workbench could help ?

Steve said...

What about mouse hover or mouse down? Would this be thought of setting the hover state of a widget to true? Seems a bit wierd. Key strokes don't seem to fit the model either.

Part of the problem is Java and the fact that it doesn't have lexical closure. This forced everyone to use inner classes and interfaces.

Steve

John Conlon said...

Perhaps we should begin looking more toward the OSGi Event Admin and some of the Enterprise Integration Patterns as a way to untangle this mess? Isn't it about time our components started acting more independent;-)