Model View Presenter pattern

I plan to follow a Test-Driven Development approach, that is, TDD (see Appendix B) while building this application. It is very easy to test our domain logic. It is not that easy to test the presentation layer of our web application if we stick with the simple .aspx/.cs approach that Microsoft gives us by default in Visual Studio. For that reason, we need to settle on a design that will allow us to test the presentation layer in as close to the same way as we would test any of our domain logic.

Note

At the time of writing this, Microsoft released its new Model View Controller (MVC) framework. While it is truly cutting edge, I couldn't introduce an unproven framework into this project at that time. Also, the way that the framework is set up would require more than simply learning about MVC for TDD purposes.

I have been using the Model View Presenter (MVP) pattern (also called Supervising Controller) to allow me to perform testing on my presentation layer for quite a while now. While I still find it a bit clunky, it is the best thing I have come across so far that allows me to perform my testing in an automated fashion. This pattern breaks down the presentation layer into three parts—model, view, and presentation. Each part has a specific responsibility.

Model

The model is a direct reference to your domain logic—the business logic layer so to speak. There is nothing more to be said! Think business layer!

View

The view is made up of the .aspx and .cs files of your webpage. These files are responsible for defining the physical items that a user interacts with in your website. They are also responsible for receiving the various events that a user raises while navigating through your site. The handled events should be immediately passed to the presenter rather than being handled in the view. It is the responsibility of the presenter to decide how to handle each event. The view is required to pass itself (by reference) to the presenter giving the presenter total control over the view.

Note

This is where the topic of Inversion of control (IoC) comes up. We will discuss this more when we get into StructureMap. If you need more information about this topic now, look here: http://en.wikipedia.org/wiki/Inversion_of_control.

Presenter

The presenter is a separate class file. There should be one presenter file per webpage. The presenter is ultimately responsible for indirectly handling events fired by the view and directly controlling what the view displays. It is the only part of the presentation layer that can communicate with the domain objects (or the model).

Tests can be wrapped around the presenter object. While this is not a full test of the UI, it is a full test of the logic that the UI interacts with. This can get tedious sometimes. To make these tests go smoothly, plan on using a lot of mocked objects either with the NUnit framework, or with the RhinoMocks framework, or something similar.

Note

Look to Selenium (open source automation tool for executing scenarios against web applications) to provide full tests of your UI. It records physical interactions with your website and replays them in an automated fashion. I find this tool to be very useful for fairly static sites. If your site structure changes frequently, your tests will have to be updated frequently. At this point the value of this test suite may be lost! To find more about Selenium, go to http://www.openqa.org/selenium-rc/.

How it works

To quickly describe how this works from a programmatic point of view, let's think about loading a list of people. The view would contain something like a GridView or some other form of Repeater. On loading, the view would instantiate its presenter and pass a reference of itself to that presenter. This passes the control of the view to the presenter. The view then calls an init method in the presenter (which you define—call it what you like). The presenter is now responsible for initializing the page (loading the initial state of the page). The presenter works with our domain objects (the model) to get a list of people. The presenter then calls methods provided by the view and passes them to its newly acquired list of people. The view then attaches the list of people to the data source of a repeater and asks the repeater to bind on that list.

If someone were to click on a person in that list, the process would be repeated up through the view, into the presenter, over some domain objects, and back down to the view. This allows us to wrap our tests around the presenter, which is part of every interaction with the view and the model. As the presenter is removed from the page itself, it is easy to get to and interact with the outside web environment!

Read more about Test Driven Design in the Appendix B at the end of this book to understand its principles better.