I just gave a short presentation at ColArc earlier on User Interface patterns. I got someone to film it, but unfortunately there is no audio. I just wasn't loud enough.
That’s ok though, it gives me an excuse to write it up!
User Interface Patterns
Smart UI (Anti-pattern)
A Smart UI is what you get when your GUI has no separation of concerns. That is, when the user interface and business logic are all mixed together. For example, if you take a form, throw a bunch of widgets on it and add some code in the event handlers.
This kind of approach is not always bad. It is fine if you want something quick and simple that isn’t going to change. For example if you want to create a quick demo, or explore how something works.
However, most of the time an application will change and that’s where things will get messy, particular if you have a lot of Smart UIs in one application.
Maintenance will get difficult. A supposedly simple change could affect anything else associated with the same class. Over time the code will likely messier and messier as more maintainers work with the same code.
Writing tests for this kind of code is typically very difficult. User interface code is the hardest part to test and if the business logic is mixed in it can make the job near impossible.
It’s called an anti-pattern for a reason.
Model View Controller (MVC)
The most famous user interface design pattern, MVC, has been around for quite a while. It was devised in the late 1970s for use in the development of Smalltalk-80. The problem its designers were initially trying to solve was that of how to bridge the gap between the human user’s mental model and the digital model of the computer.
Eventually they whittled it down to the famous MVC triad we know today representing 3 key concerns:
Controller – Represents interactions, typically with the mouse or keyboard, or in the case of web applications, in the form of HTTP requests.
View – Renders the graphical output of the application
Model – Everything else. In particular this includes the data and business logic.
There are numerous other “triad” style user interface patterns. They all tend to feature some kind of concept of model and view, but the 3rd part (in this case the Control) tends to vary.
The other distinct trait of the MVC is that it is extremely loosely coupled. The Model knows nothing of the View or Controller, and similarly the View knows knows nothing of the controller either. One particularly useful side effect is that it is possible (and completely normal) to have multiple views for any given model. It is also relatively easy to change out parts (for example the viewing technology).
Testing is relatively easy. The Model and Controller are easy to test.
Model View Presenter (MVP)
During the 90s not everybody was satisfied with Model View Controller. In particular some developers working with rich application interfaces were creating GUI’s with highly detailed state changes and high degree with user control over the environment. At that time the typical MVC implementations did not handle this kind of activity as efficiently.
The creators of MVP ended up with a new model by shifting the MVC responsibilities around in what they called “Twisting the Triad”.
So instead of a controller, you get a presenter instead. The presenter has much of the computational logic of the View, but also takes over the Application Model aspects of the Model. That is, the part of the model in charge view state changes, such as which widgets are visible or not visible.
The other twist is “Controller” behavior is moved into the View.
This gives us this:
The MVP architecture works really well from a testing point of view. First you develop the model with a full set of tests. On getting that working you write the Presenter to handle as much of the viewing logic as you can, but out showing anything. This part two is therefore very easy to test. The actual view code is typically difficult to test, but in this architecture the view code is kept to a bare minimum, with events getting delegated to the Model. This means the untestable code is being kept to a bare minimum.
The code reuse is good too. A single presenter can be reused with multiple views if the functionality is similar. Because the View and the Presenter are tightly coupled it is easy to support databinding.
There is one complication I have not covered yet. There are actually 2 variants of this pattern:
The style I have described up till now is closest to the Passive View variant. The Supervising Controller variant typically is used when you want to bind the view to model directly.
This pattern is a little more specialized; it is designed for rendering hierarchical views quickly.
For example, suppose you have a form based application. The form is the top triad node. Descending nodes might include the titlebar and client frame. The client frame in turn may have a number of widgets. Some of these widgets may in turn be composed of more widgets.
Each triad is similar to the MVC parts:
Abstraction = Model
Presentation = View
Control = Controller
The Control handles communications with the Abstraction and Presentation, also with other Controls in thee hierarchy.
The clever bit is that the Abstraction and Presentation parts are completely isolated from the outside world. This means they work really well in a multitasking context.
Hierarchical Model View Controller (HMVC)
In 1987 JavaWorld magazine published an article on HMVC, which looks almost identical to PAC. Apparently the authors were unaware PAC already existed. HMVC is very similar to PAC but there are some small differences. In particular, it is less strict about isolating the Abstraction and Presentation; they are allowed to communicate with each other from within a triad.
This pattern is very specialized, it is designed for use in .NET’s WPF and Silverlight frameworks.
Both these frameworks configure the View in the form of XML based properties (XAML). In a way working with XAML can be a bit like developing for Webforms, it is possible to respond to events in the Code-Behind. That of course would give you a Smart UI, so not ideal. Implementing classic UI patterns such as MVC or MVP would be very difficult. Instead these frameworks offer an alternative by allowing a ViewModel class to be referenced as a resource in the XAML.
Using the ViewModel we get a slightly unconventional triad structure:
The ViewModel class is able to work part of the UI in the form of Command objects for handling state interactions. Also it gets access to part of the Model data needed for the specific view. This model data is transitory, and can be committed back into the model when the view changes are complete.
A common question with MVVM is “How is it different to MVC and MVP”?
The MVC parts are extremely loosely coupled. Also the Controller does not do much more than pass messages to the Model or View while the ViewModel is responsible for doing a lot more.
The MVP looks similar at a glance, but in MVP the Presenter is the more dominant than the View. In MVVM the View owns the ViewModel. Also the ViewModel only exists if there is a View, while in MVP there can be multiple views to a Presenter.
So which do you use? Well, personally I would almost always stick the MVC pattern because there are many great frameworks available:
Ruby on Rails, Spring MVC, ASP.NET MVC, Monorail, etc
I think MVP looks useful, but I only know of one a couple of frameworks:
Web Client Software Factory - MVP Bundle (Thanks Jeronimo for point this one out!)
Yes, peculiar as it might sound, MVC# is actually an MVP framework.
However, if I had to implement a pattern myself, it could go either way. I have recently spent time refactoring a “Smart UI” into an MVC structure in a Windows C++ application. In hindsight I think it would have been easier to refactor it into a MVP structure, because it’s hard to separate controller logic from the view with CWnds andit would involve less refactoring steps.
I think PAC/HMVC sounds very cool but I doubt I would ever run into a scenario where the optimization would be make it worth while. Looks like it could be fun to play with though.
And of course MVVM is pretty much the only game in town if you want to write a WPF or Silverlight application.
Everything described here was pieced together from various places. Here are some of the them: