In response to my Friday entry, Jeroen asked about Eclipse application design; how do you architect an Eclipse application? It’s a good question.
I tend to fall back on classic patterns. As a start, I separate my application into multiple layers, employing the well known model-view-controller pattern. Typically, I’ll separate the layers into separate plug-ins. The “core” plug-in contains the model objects, and very often some kind of Facade to access the model objects. This “core” plug-in does not have any notion of user interface. Ideally, it also has no notion of storage (i.e. databases). One or more “view” plug-ins make use of the “core” plug-in to gain access to the object model and business logic to present a view of the models for the user. I tend to roll the notions of controller into the “view” plug-in.
This style of architecture is very similar to what you might find in a Java EE application: a web models (WAR file) contains servlets as controllers and JSPs as views; other JAR files contain the business logic and object model.
The Eclipse component model provides a great service in this style of architecture. By imposing a visibility model, Eclipse actively discourages the developer from including user interface code in the model (of course, real programmers can figure out ways around this). The collection of “view” plug-ins all have the “core” plug-in (and others) as dependencies: the views can see the core, but not the other way around. By encouraging this style of separation, the level of coupling in the code is reduced which makes the code far less brittle in the face of change and infinitely more reusable.
By separating out the model code in such a way that it can exist on it’s own, testing also becomes easier. Lately, I’ve been using fragments to build my test code (I used to just use another plug-in). Fragments are quite handy for building tests as they are merged together with the “host” plug-in at runtime and so can access the code being tested as though the tests were part of the host plug-in: you don’t have to expose any more of your plug-in at runtime than you want to and can still provide good test coverage.
A few paragraphs back, I stated something about ideally keeping storage or data access code separate from the core as well. In the beginning, I tend to put the data access code into the “core” plug-in. Over time, this code migrates out into its own separate plug-in to the point where the data access code is just another “view” of the data (in my object-centric view of the world, the user interface and database are just ways of looking at my objects).
So, at a high-level, there you have it. An Eclipse RCP application should be constructed of multiple plug-ins. Ideally, at the core of this set of are one or more plug-ins that constitute an application model that exists and works independent of any notion of user interface. Additional plug-ins provide a user interface along with any control glue required between the model and the view. And somewhere in there are still more plug-ins that provide data access.
All of the RCP examples that I’ve been discussing over the past few months do all of this. Besides reducing coupling and making reuse easier, I’ve also found that it makes the application far easier to extend; this sort of factoring of the application makes leveraging Eclipse’s extension-point mechanism a lot easier.
I don’t think that this sort of architecture has anything to do with Eclipse. It’s classic application development best practices. Fortunately, Eclipse encourages us to use them.