In a previous entry,
I discussed how using mix-ins lets you compose your code to a finer level and
allows you to create smaller bundles of functionalities that you can import and
use on demand.
Of course, it is quite possible to take this practice too far and end up with
code that is not only broken down too much but also spends most of its time
exchanging messages between its various components using more complex
communication ways than it should. Sometimes, it just makes sense to group
certain methods and fields in the same class.
Formalizing the communication between units of code is a subject that has
received very little exposure until recently, and when you are trying to pass
information between different classes (A to B) or different packages, you
typically use one of the following techniques:
- Have A create an instance of B with the right parameters and invoke a
method on it.
- Have A create an empty instance of B, call a few setters then invoke a
method on it.
- A receives an instance of B that has been created somewhere else and
invokes a method on it.
The hard coupling of A and B is a topic that has already been covered many
times and can be improved by either using interfaces or dependency injection.
However, there is a third way to accomplish this that I am hoping will be used
more and more: use a plug-in architecture.
I have written quite a few Eclipse plug-ins these past years (and more
recently, RCP applications) and I started noticing two very interesting trends
in the code that this environment made me produce:
- Resuming development on a plug-in I hadn’t worked on for a while was
very easy, because the various parts of the plug-ins were so clearly
isolated from each other that I only needed to brush up on a very small
portion of my code to be able to modify it.
- Adding features to an existing plug-in didn’t require understanding the
existing code base: all you need to do is read some documentation about the
area that your plug-in will depend on and focus on that part only.
In case you were wondering about the reasons behind the explosion of Eclipse plug-ins, look no
further: the reasons are outlined above, and the bottom line is that the
learning curve to add to existing code with the Eclipse model is extremely small
(and can actually go down over time). When new developers join your
project, they don’t need to learn a new architecture because that architecture
has been formalized by Eclipse and everybody now agrees on how the plug-ins are
declared and how they interact with each other. The rest is, literally,
The net result of this new paradigm is that all Eclipse plug-ins and RCP
applications are nothing more than a set of isolated modules that gravitate
around the Eclipse core.
Another interesting thing about this architecture is that even the
communication between these plug-ins is formalized. Not only does the
plug-in model offer all the benefits of dependency injection, it also formalizes
how you can receive notifications from other plug-ins, how you can emit
notifications yourself and more importantly, hides all the details pertaining to
upgrades, classloading, and, of course, provides an impressive set of
functionalities that cover everything you will ever need for a client-side
application, including integration with the host operating system (Windows,
MacOS and GTK/Gnome).
Thanks to Eclipse and the RCP, Java is finally on its way toward having a
true component model. Still not as powerful as COM (only in-process mode
is supported), but definitely one step closer.