UI Design Using Model-View-Presenter (Part 1)

Introduction

Current tendencies and best practices in software development lead to the common pattern that a software system has to be solid, scalable and reliable. In order to comply with those three requirements, two aspects have to be considered during design phase: Code coverage and separation of concerns.

What? Ok so, code coverage is a metric that indicates how much of the code is being covered by unit tests or, in other words (English, plz), how testable is the source code we have written during those lovely 18-hour shifts. Yes– unit testing is SO important it has its own goddamn metric.

Then we have separation of concerns, which plays close with code coverage, since, in order to have handsome unit tests, we need to give each component of the system a single concern to deal with. In software design, the milk man cannot deliver newspapers around the neighborhood. Each component has a specific well-defined responsibility and it has to stick to that scope.

But what does all of this has to do with user interface design? Well, user interface code is the number one culprit of most software design flaws since it often lead developers into breaking these two design aspects specifically. Is a common well-known scenario where a class that represents a window to be rendered on-screen also performs business logic validations and queries the database directly. This not only screws up the whole idea of separation of concerns but also makes unit testing of that particular class almost impossible, punching code coverage right in the face.

That’s right. Developers are well-known for not being too skilled at designing pretty GUIs. However, when they nail it, they screw infrastructure up. Go figure.

Anyways, this three-part series of articles intend to demonstrate clear examples of both the traditional way and the “awesome” way (don’t mind quotes at all) using the Model-View-Presenter pattern in order to improve overall infrastructure design of the application user interface.

Examples will be provided in C#, using Windows Forms. The example application is Mono-compliant, so it can be compiled to run in several platforms using the Mono Framework. An additional version for Java using Swing will be provided at the last article of the series.

The Scenario

For our practical example, we are going to build a small application that displays a list of clients available in a data source to the user on-screen. The user will then be able to select clients from the list and view additional details like age, gender and e-mail address. You get the idea.

The clients will be queried from a repository which, for matters of simplicity (I’m just THAT lazy), will return data from a pre-defined generic list. For a start, here is the repo source code:

using System.Collections.Generic;

namespace Codenough.Demos.WinFormsMVP
{
   public class ClientRepository
   {
      private IList<Client> clients = new List<Client>()
      {
         new Client { Id = 1, Name = "Matt Dylan", Age = 28, Gender = "Male", Email = "mattd@none.com" },
         new Client { Id = 2, Name = "Anna Stone", Age = 22, Gender = "Female", Email = "ann@none.com" }
      };

      public virtual Client GetById(int id)
      {
         foreach (Client client in this.clients)
         {
            if (client.Id == id)
            {
               return client;
            }
         }

         return null;
      }

      public virtual IList FindAll()
      {
         return this.clients;
      }
   }
}

Traditional UI Design

Read “Effective”, Not “Efficient”

Traditional ways to develop user interfaces tend to give all responsibility to it of the data it shows, including: user input, data validation, error handling, database access and all other sorts of magical and mysterious things. The following piece of code creates the window containing a list box, to display available clients; and a series of text boxes showing additional stuff related to the client selected on the aforementioned list box and a really REALLY good looking close button.

using System;
using System.Windows.Forms;

namespace Codenough.Demos.WinFormsMVP
{
   public partial class ClientsForm : Form
   {
      private readonly ClientRepository clientsRepository;

      public ClientsForm()
      {
         this.clientsRepository = new ClientRepository();

         InitializeComponent();
         BindComponent();
      }

      private void InitializeComponent()
      {
         // Create and initialize window controls. Omitted for brevity..
      }

      private void BindComponent()
      {
         this.closeButton.Click += OnCloseButtonClick;
         this.clientsListBox.SelectedIndexChanged += OnClientsListBoxSelectedIndexChanged;

         this.clientsListBox.DisplayMember = "Name";
         this.clientsListBox.ValueMember = "Id";
         this.clientsListBox.DataSource = this.clientsRepository.FindAll();
      }

      private void OnClientsListBoxSelectedIndexChanged(object sender, EventArgs e)
      {
         var selectedClientId = (int)this.clientsListBox.SelectedValue;
         var selectedClient = this.clientsRepository.GetById(selectedClientId);

         this.clientNameTextBox.Text = selectedClient.Name;
         this.clientEmailTextBox.Text = selectedClient.Email;
         this.clientGenderTextBox.Text = selectedClient.Gender;
         this.clientAgeTextBox.Text = selectedClient.Age.ToString();
      }

      private void OnCloseButtonClick(object sender, EventArgs e)
      {
         Application.Exit();
      }
   }
}

First thing I would like to mention here is that this example satisfies all acceptance criteria (you know, what it is expected to do) we established for the end-product. It shows the list of clients, each time one is selected details of that client are displayed in the details group box and all that magic.

So, what is so bad about this code? It does what it should, and best of all: in roughly 49 lines of code. Well, as frustrating it might seem, something effective is not always efficient. The previous piece of code breaks pretty much all aspects of good design. Martin Fowler might even shed a little tear just by looking at it.

Testing What Cannot Be Tested

As I mentioned at the beginning of the article, unit test code is as important as the actual business source code. Always remember that, lad. Let’s define a couple requirements this application needs to satisfy.

The clients application should (as in “has to”):

  • Show all clients in the list box when it loads.
  • Show details of the first client in the list when it loads.
  • Show details of a client and show it when the user select an item in the clients list box.

Now, let’s write test method stubs for these:

using NUnit.Framework;

namespace Codenough.Demos.WinFormsMVP
{
   [TestFixture]
   public class WhenClientsWindowLoads
   {
      [Test]
      public void ItShouldLoadAllClients()
      {
         // ...
      }

      [Test]
      public void ItShouldShowFirstClientOnListDetails()
      {
         // ...
      }

      [Test]
      public void ItShouldShowClientDetailsOnListItemSelected()
      {
         // ...
      }
   }
}

When looking at these tests, we can notice they are specific to the presentation portion of the application. We are not testing data access (the ClientRepository class) or rendering-related stuff. By using the code example provided earlier, our tests could fail or pass depending of:

  • The repository classes.
  • The data coming from the repository.
  • The stability of the actual Windows Forms libraries (better known as the “Please Don’t Screw Up, Microsoft” prayer). 

So, we would have to adapt our tests for cases when the ClientsRepository class returns unexpected data or an environment-related exception occurs when rendering the window on-screen.

We simply can’t perform proper testing of the source code as it is right now. At this point, code coverage has been compromised; not even talk about separation of concerns. The ClientForm class does friggin’ EVERYTHING.

But fear not. Fortunately for us, some nerds locked up in a server room under an average temperature of about -5 degrees celcius already encountered themselves in this predicament and figured out a way to make of the world a better place: The Model-View-Presenter pattern.

The Model-View-Presenter Way

The Model-View-Presenter pattern was hatched in early 90′s at Taligent and popularized later on by a paper written by some really smart fella called Mike Potel; Taligent’s CTO at the time. The pattern was later used in Smalltalk user interface framework and adapted to Java when it started gaining popularity.

In a very general scope, the MVP pattern seeks to leverage the principles of separation of concerns, leaving each part composing the user interface code with a well-defined responsibility. Wow, that sounds awesome. Right?

Dropping the geek lingo, it means that, in our clients list application, the window should only care about showing data to the user on-screen and nothing else. No data-access, no business logic, no NOTHING.

The pattern is composed of three parts:

  • Model: The stuff that will be displayed to the user. It is updated as the user inputs new information on-screen.
  • View: As the name implies, the View is either a window, web page, app, smoke signals or anything used to show the Model information to the user and let it modify it as it pleases.
  • Presenter: The Presenter is actually a dude who stands right between the View and Model. It has the responsibility of providing the View with the data from the Model and validate data coming back from the View.

MVP Diagram

You might be asking yourself what in the world could be so good about separating the presentation layer of an already multi-layered software architecture in even more parts (or, source code “onionization”). Well, the MVP pattern allows us to fully test the presentation layer of our application regardless of the other layers; business and data-access that is.

In the case of our application, all unit tests required to comply with acceptance criteria are intended to validate user interface initialization and logic flow, task the Presenter is in charge of; window rendering is problem of the View and model data-access is responsibility of the ClientsRepository, which we don’t really care about whatsoever.

Coming Up

So, this concludes the first part of this article. We have reviewed some of the key aspects behind proper code design: code coverage and separation of concerns; which is important for what’s coming next. In the next part we will be exploring how to actually implement the MVP pattern to buff up our previous example and hopefully settle things up for good.

Go read Part 2! ;)

4 thoughts on “UI Design Using Model-View-Presenter (Part 1)

  1. Pingback: UI Design Using Model-View-Presenter (Part 2) | Informatech CR Blog

  2. Pingback: UI Design Using Model-View-Presenter (Part 3) | Informatech CR Blog

Leave a Reply

Please log in using one of these methods to post your comment:

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