Saturday, 10 January 2009

Presentation patterns

To kick off the few posts I’ll be doing on presentation patterns I’d like to quickly discuss the basics of the common ones. There are plenty of places on the web that discuss technology specific implementations of these patterns but think that it is important to also understand them without thinking about implementation.

I felt I really learnt the most about these patterns when I moved from doing them in a rich client environment with WinForms to the web with WebForms. I had to focus on the concepts behind what I knew and try and forget the specific implementation techniques.

Now as a disclaimer I don’t pretend to be an expert on everything UI related and I don’t intend this post to be all inclusive or definitive. But I do want to lay the foundation for some of the stuff I’d like to talk about in the next couple of posts.

View/Model Separation

Generally all presentation patterns have the concept of View/Model separation at their core. The idea is that the objects dealing with the domain should not be complicated by presentation concerns. This also means that you can in theory implement the views in a different technology without having to replace the core domain code.

The Model is often the most confusing part of the common patterns. The Model effectively includes any part of the system that is not presentation or infrastructure. In reality the Model simply means the portion of the domain that is relevant to the current use case. It includes the domain model objects such as Customer, Order etc. as well as objects such as services, factories and repositories.

The View is much simpler to define. It is simply a single representation of the Model. It is not uncommon for a system to have multiple views of the same model which present it in ways suitable for a specific context. The important thing to bear in mind here is that synchronisation of views in this type of system happens in the Model i.e. the Model is updated and then all views should reflect the change.

The common patterns are all based around these two concepts. What is different about them is how input is handled and how the components involved interact.

Model-View-Controller (MVC)

Model-View-Controller or MVC is the earliest of the main patterns. It was developed in the 70’s before modern presentation platforms existed and as such it doesn’t really make sense in many contexts today (for example when doing Windows programming).

As its name suggests it is made up of a View, a Model and a Controller which co-ordinates between the other two. The main features of MVC is that the Controller receives the user input directly. The importance of this becomes more apparent when you look at MVP. The basic workflow of MVC is that input is received by the Controller. The Controller then passes this input on to the relevant part of the Model which acts accordingly, often updating parts of the Model. The View then reflects these changes in the Model back to the user.

Generally the View and the Controller do not communicate directly. Instead the Model can be seen as the part of the system that connects them.

I often like to think of MVC in the context of the kind of apps that were originally written using it in which the user does not interact directly with the view but with some other piece of hardware. The hardware sends signals to the system which are dealt with by the Controller and the view is purely a one way view of the model. As we shall see with modern rich clients this pattern doesn’t make any sense any more, though when looking at the web world (and ignoring client side code) MVC is ideal.

image

Model-View-Presenter (MVP)

Modern rich client UI frameworks have the concept of Forms and Controls which not only display information to the user, but also accept input. Using this idea you can say that the View accepts the input instead of the controller. Because of this difference when compared to older presentation ideas the Model-View-Presenter (MVP) emerged.

Fundamentally the only difference between MVC and MVP is which component first receives the user input. The MVP pattern replaces the Controller with a new component called the Presenter (though generally the two names are interchangeable), but they both have pretty much the same role. However the View now receives the input and then sends a message to the Presenter which then carries on as the Controller would in MVC.

Modern MVP is split into flavours which differ in how the last part of the cycle is implemented i.e. how the View reflects the changes in the Model. Generally there are two main flavours known as Supervising Controller and Passive View, though in reality there are a lot of variants which often sits somewhere between the two.

Supervising Controller

Supervising Controller is effectively the original version of MVP and the closest to the original MVC pattern. Personally it is the style which is closest to how I prefer to implement it. In this pattern the View automatically reflects changes in the Model by taking advantage of the facilities of the presentation framework, which most often means using some sort of declarative binding. Where some more complex situation occurs the Presenter may manually update part of the View.

The idea with Supervising-Controller is that by removing the simple UI operations which can be done by the framework we reduce the responsibilities of the Presenter and focus on the complex parts of the presentation.

 image

Passive View

Passive View on the other hand moves all UI logic into the Presenter, which now has both the responsibility of interacting with the Model appropriately for the received input and of updating the View to reflect those changes. 

This approach mainly came about because people wanted to be able to increase testability and so making the View simple and dumb and putting the logic into the Presenter we can test that a faked out View is updated as we expect by the Presenter.

image

The Passive View pattern is good for simple scenarios when the view is fairly simple. It can become cumbersome when the amount of the View to be updated becomes large.

Another important thing to point out is that while Passive View came about to increase testability, that does not mean that Supervising Controller is not testable, the testability is largely down to the implementation chosen.

Hopefully I’ve done a decent job of explaining the basics of the various patterns. In reality the implementations of each varies based on the developer and the frameworks being used. Its is also true that there isn’t one single pattern that fits all situations. By understanding the core ideas of each however, we can better decide which model fits our needs

2 comments:

Tim said...

Very well explained, Mike. We often get lost in the implementation details. It's good to take a step back and think about the original intention of these patterns. I look forward to your next post in the series!

Paul said...

Yeah good post Mike. Have read a few posts / books on this over the years and always seem to come away not quite knowing the differences but this clears up some of the confusion.

Cheers