Perspective Layouts – Programmatic vs Declarative

One issue that developers new to RCP face is whether to add UI elements programmatically or declaratively. In my experience, most initially choose the programmatic approach because it seems more familiar. You know, why mess with extension points when you can just code it up and be done with it.

But it’s almost always better to do things declaratively through extension points, the main reason being that doing so allows you leverage the power of RCP as a modular user interface framework. To illustrate this, let’s look at our options for laying out perspectives.

Programmatic Layout = Centralized / Hard Coded

Here is the simplest code needed to add a view to a perspective programmatically. To do so, we implement the IPerspectiveFactory interface and add a view using its string id.

public class MyPerspectiveFactory implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {
		layout.addView(MyView.ID, IPageLayout.BOTTOM, 0.5f, layout.getEditorArea());
	}

}

The problem here is that we’ve coupled our perspective to the view being added. This view may exist in the same plug-in as the perspective, but often it does not. If the view is in a different plug-in, we have to declare a dependency on that plug-in just to add the view. It’s possible to reduce the coupling somewhat by replacing MyView.ID with the actual string id itself, but hidden dependencies based on string equivalency are arguably even more smelly.

In the end, a programmatic perspective layout results in a hard-coded and centralized architecture looking like this.

perspective-layouts-central

Declarative Layout = Decentralized / Modular

The declarative approach based on extension points resolves these issues. To layout a perspective declaratively we extend the org.eclipse.ui.perspectiveExtensions extension point.

   <extension
         point="org.eclipse.ui.perspectiveExtensions">
      <perspectiveExtension
            targetID="com.mycompany.myperspective">
         <view
               id="com.mycompany.myview"
               minimized="false"
               ratio="0.5"
               relationship="left"
               relative="org.eclipse.ui.editorss">
         </view>
      </perspectiveExtension>
   </extension>

Using this approach, each plug-in adds the views that it knows about, resulting in a decentralized architecture where the plug-ins containing the views are now in control.

perspective-layouts-decentr

Note that we have not eliminated all coupling, as the perspective extensions still need to refer to the perspective by its string id, but this is not as bad as it sounds. Perspectives are much more static than views – you typically define them and make few changes afterwards. Views, on the other hand are often moved from one plug-in to another or have their purpose (and potentially their id) redefined. Decentralizing control allows you to make these kinds of changes without breaking the perspective layout.

Conclusion

Adding UI elements declaratively is definitely the way to go. It gives you much more flexibility (e.g. you can add views to perspectives you didn’t create) and also allows you to leverage the modular nature of the framework.

Sure, there will always be cases where a declarative approach cannot be taken, particularly when some part of an API is not yet surfaced in the related extension point. But in the absence of such a need, I urge RCP developers to always turn first to the extension point mechanisms and fall back to programmatic approaches as a last resort. As your application evolves over time, you’ll really come to enjoy the flexibility and increased reusability that a declarative approach makes possible.

Advertisements

10 Responses to Perspective Layouts – Programmatic vs Declarative

  1. Matthias Treitler says:

    Funny that you CAN arrange all your view parts decaritively with the perspectiveExtensions extension point but you MUST implement a IPerspectiveFactory class for the perspectives extension point… 🙂

  2. Patrick says:

    Hi Matthias,

    Yeah, it is funny that you may wind up with an empty perspective factory. But there are some uses for the factory, even if you go with a declarative approach (e.g. controlling the visibility of the editor area).

    — Patrick

  3. Tonny Madsen says:

    I agree completely with you. In fact I have just one common perspective class in my applications – one that will take an argument via IExecutableExtension to decide whether to use the editor area or not.

    One of the execises that we do in RCP training is to show that the declarative approach is easier than the programmatic approach.

  4. Patrick says:

    HI Tonny,

    A common perspective class is a great idea. I’ll definitely add it to the UI framework that I suggest to new RCP developers. Thanks!

    — Patrick

  5. philk says:

    @Tonny Madsen: How do one add initialization data to a PerspectiveFactory declaration? In PDE its not directly supported. Can I just add it to the plugin.xml myself?

  6. philk says:

    I just used the “inline” method and appending the “editorArea” parameter delimited by “:” to the class name. It works!

  7. Jon Barrilleaux says:

    I have been trying to climb up the RCP learning curve for a couple months now. The goal is to develop a really rich custom app that looks and feels like “our” app, not an “eclipse-and-the-kitchen-sink” app. This is turning out to be a surprisingly hard thing to do, especially using the declarative approach that the gurus are pushing.

    In Java, I can use a powerful IDE for refactoring, navigation, and search. I can use design patterns, inheritance, and delegation — all the tools of good software design. With the declarative approach, it seems, I am reduced to stone knives and bear skins.

    Am I drinking the wrong koolaid or what?

    BTW: It would be fantastically wonderful if there were a duality in the framework so that extensions could be added programmatically and/or declaratively, with both being on equal footing. From everything that I have seen it is one or the other, and never the twain shall meet. Is there some bridging mechanism that I’ve overlooked? If not, this seems like a rather brittle and inflexible approach on the part of the framework architects.

  8. Patrick says:

    Hi Jon,

    I know from experience that it can be hard to make the transition from a programatic approach to a declarative one. But what the declarative approach provides is an extremely flexible modular architecture. I often tell people who dislike a declarative approach to really think about whether they need this flexibility. If you don’t, then by all means, do thing programatically.

    Having said that, I’m not sure how doing things declaratively would stop you from using the software design tools you mention. Can you give me an example where you feel constrained? It would help me to understand what issues you’re facing.

    As far as adding extensions programmatically, there are many cases where the same thing can be done programmatically or declaratively. For most extensions there is a corresponding API that allows you to manipulate related elements, for instance the menuing, command and handler APIs. There are some things that are difficult to do programmtically (e.g. add a wizard), but these are more the exception than the rule. Is there something in particular that you’d like to do programmatically that isn’t supported right now?

    In any case, if you have any questions or issues getting your app to look or act the way you want, feel free to email me. I’d be happy to help in any way I can.

    — Patrick

  9. Lars Vogel says:

    Hi Patrick,

    I agree that the declarative approach is the preferable.

    I adjusted therefore my Eclipse RCP tutorial (http://www.vogella.de/articles/RichClientPlatform/article.html) so that it first demonstrates the usage of perspective extension and then afterwards demonstrates the usage of code.

    I believe it is tempting to stick with the things you first learn. As the Eclipse view RCP template uses code to stick the view to the perspective most of the people stay with this approach. A Bug report is open for this https://bugs.eclipse.org/bugs/show_bug.cgi?id=265231

    Best regards, Lars

  10. Patrick says:

    Hi Lars,

    I agree about the template and voted for the Bugzilla entry. Thanks for doing this!

    — Patrick

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: