Friday, July 24, 2009

Binding or not binding. It's a problem.

Binding or not binding. It's a problem.

Recently, I'm finishing my one personal RCP project. I decide to touch the JFace data binding framework. To be exact, it now should be called the "Eclipse data binding" framework. The data binding stuffs have been one part in the core of Eclipse, and the JFace data binding is just one application of the Eclipse data binding. I have not played with the data binding since it's born. One main reason is that I don't think the listener boilerplate codes are hard to write or error-prone, however the databinding introduce many new concepts.

With the entrance of the databinding to the core of Eclipse and, of course, RCP, I should put it into my toolbox if I don't waste some functionalities and hard disk space.

Now, the target of my adventure is to customize a databinding implementation for Nebula PShelf.

Firstly, I take 2 days to read the most of materials from Eclipsepedia, EclipseCon, blogging or anything else. Frankly speaking, I don't like almost of them. Because they don't take care of the the customization of databinding which is just interesting for me. However, for newcomers, I'd like to suggest two reading - the old Eclipsepedia pageRCP Mail 2.0. And don't forget the offical databinding blog.

Then, I start to dig into the source of databinding. After my familiarity with the databinding boilerplate codes and others(how the framework works),  the properties API appears. The properties API has been introduced into the Eclipse data binding framework from 3.5M5 to solve some hard coupling(then "Observables are hard to implement") in the framework. The properties API use the "Fluent Interface" which is one nice API style thought by me. Cong! With the help of the properties API, I succeed in finishing my PShelf databinding customization adventure.

Lastly, I just drop a few comments on the Eclipse Data Binding framework from my eye, 

1. The framework seem a little over-designed.
In the runtime, the call stack will be much long even in the simple case compared to the traditional listener pattern.
And, many APIs are just delegates to other APIs. Like,
public static IObservableValue observeValue(Realm realm, Object bean,
String propertyName) {
return BeanProperties.value(bean.getClass(), propertyName).observe(
realm, bean);
public static IObservableValue detailValue(IObservableValue master,
IObservableFactory detailFactory, Object detailType) {
return new DetailObservableValue(master, detailFactory, detailType);
Thats means, many different APIs get into the same functionality. Facade? For the newcomers, this causes many confusions(schizophrenia?^_^). I just stick to use the properties API and see no side-effect. I suggest to making the old API "deprecated"(Orz, for the compatibility, they will be still live in a short or long term.)    

2. org.eclipse.jface.examples.databinding.snippets are a little out of date. 
Some demos use the new APIs. Some others use the old APIs or mixed ones. Even some ones are confused for newcomers.  For instance, in the snippet class "Snippet002UpdateComboRetainSelection":
 IObservableList list = MasterDetailObservables.detailList(
 BeansObservables.observeValue(viewModel, "choices"),
 getListDetailFactory(), String.class);
 private static IObservableFactory getListDetailFactory() {
return new IObservableFactory() {
public IObservable createObservable(Object target) {
WritableList list = WritableList.withElementType(String.class);
list.addAll((Collection) target);
return list;
This demo seem not related to the Master-Detail pattern. This bulk codes are workable, but not elegant. I modify them like the below,
IObservableList list = BeansObservables.observeList(viewModel,"choices", String.class);
Everything is still nice:)

3. Some API classes can provide more convenient APIs. 
One example is the newcoming helper, ViewerSupport.bind(...),  you can see the compact usage in this Matthew Hall blogging entry. For the default condition, we are happy to use this shortcut method. However, when we want to customize every providers, we are forced to use the old boilerplate codes.  It's hoped that, we can add some provider accessor/mutator method in the ViewerSupport, like, get/setContentProvider, get/setLabelProvider. After that, we can live in a more concise room more happily.

4. Databinding framework has been mature to use in mainstream development(oh, some companies have done this long long ago^_^)
Although it still needs the the listeners to implement some functionalities under some complex scenarios, the databinding have covered most common UI usages. With the R3.5 properties API, we can code in a concise style from the UI application to the databinding customization. However, the databinding framework has a relatively high learning curve, in comparison to the traditional listener pattern. The listener pattern is more straight and debuggable. You can stay in the traditional listener codes if you think it is enough.  Indeed, the Eclipse Databinding seemly provide more advanced features such as the before/after validation, which need a careful design if you try to code from scratch. The learning time is the price of any framework. The only thing is whether we choose a right framework. The Eclipse data binding framework is just the right framework. 

Next, I'm considering to taste the EMF Data binding API (with the new properties API) some time.


No comments: