To separate the logic from the presentation, we have the Model-View-Controller (MVC) pattern. This pattern is widely accepted as it has proven its worth. This is not what I will discuss here, in this blog post I am looking at how we can make components from the UI re-useable in multiple screens. Another way to put it is creating an Object-Oriented UI, which makes is sound easy as we are all familiar with that. There are however some issues related to UI that make it a lot harder.
As a good Object-Oriented developer, of course you want to have clean and re-usable code where each part has its clear set of responsibilities. The same should hold when creating a UI, as often you will have elements that come back in multiple screens. Sometimes re-using these elements are easy such as having a toolbar shown, but other are much more complicated.
Recently I encountered this problem again when I was designer a UI with SWT. While SWT already has many elements that can be re-used, I wanted to take it to an extra level and make a group of these elements re-useable. Some questions however where to be solved and problems had to be solved.
First I tried putting the elements in a separate composite as that made the most sense to me. The problem with this is that the composite will layout the elements independent of the others. Since I also wanted to add elements above and below the composite the right layout was very important. I solved this by grouping the elements in a pseudo-composite, instead of using a composite of SWT, I create something that looks like it, but attaches the elements directly to the parent instead. This way the parent can layout all the elements, including the ones inside the ‘composite’.
Another problem is the interaction between the composite and the actual screen it is shown in. You might want for instance that if some field is not filled in properly an error message is shown. This either requires the screen to ask the composite for errors, or the other way around that the composite notifies the screen of these events. The first solution requires some kind of polling to check if there is an error, while the second one can happen event-based. By adding a listener to the composite (similar to how SWT does it), the screen can be notified about changes and update it’s view.
Using the MVC pattern, the composite would write it’s data to the model it belongs to. Since the screen encapsulates the composite, so should it’s model. That way it may be easy for the screen to get the data that is stored inside the composite. The screen can determine this way whether it has to update it’s view, however it still needs a notification that something was changed or we have to use polling again.
Using the MVC pattern in such a way also raises questions about the models and how they interact. Their interaction should be the same as the view. At the same time letting the screen access the data of the composite may not be such a good design as it breaks the separation.
My personal option goes out to allowing each component verify itself and make the result of those checks publicly available. In my opinion that is the only decent solution considering good Object-Oriented design principals.