Saturday, April 22, 2006

Model View Controller

What is MVC?


When developing a web application that has anything other than the simplest page navigation, it is extremely important to seperate the presentation, the business logic and the control of the page-flow. The best way to do this is by using the Model View Controller pattern (MVC).
The 'Model' is the part of the system that deals with the business logic, it is the logical representation of the problem domain. In OO this would give your abstrations such as Employee, Customer, Payslip etc.
The 'View' refers to the web page layout and presentation of the information to the user. In a web application, this is usually represented by markup.
The 'Controller' is the part of the web application that takes an event (usually a user action) and decides how the system should respond to it. It performs any updates that are required to the Model, and then decides which page (View) to display next.

MVC in J2ee


This pattern is implemented in the Apache Foundation's Struts project, an opensource Java framework. The specific pattern is called MVC II, which is a Front Controller implementation. A Front Controller is where the Controller, not the View, is the first to receive the user action and then decides what actions to take in response. Once it has performed any actions it needs to in response to the event, it decides which page to display. However, a particular event isn't tightly coupled with the page is displays, and to ensure that you can easily change the destination page, each page is responsible for getting any information it needs to display from the Model, and this information is not passed by the Controller to the View.

MVC in ASP.NET


In my opinion, the MVC II model is the best option for any enterprise scale web application. However, I tried to apply this to an ASP.NET project, and I found myself battling against language features every step of the way. The main issue is that ASP.NET by default employs the Page Controller model, where Postbacks are used to enable the page to deal with any events that result from user interaction with any of its controls. Therefore you often end up in the awkward position of handling the Postback in page X , and in response to that action, you actually want to be displaying page Y. It appears that, unless you want to take on the additional complexity of Microsoft's User Interface Process Application Block, it makes sense to accept that a lot of the language features demand that you use the Page Controller pattern, and try to make the best of it. I have read several Microsoft articles that claim that the ASP.NET page code-behind feature seperates the View (the markup) from the Controller logic (code-behind). This is not really true, as the code-behind contains a muddle of View logic and Controller logic. To ensure that you get an MVC seperation of concerns, the code-behind should contain only 'View' logic, and the Controller logic needs to be seperated out from this. As the ASP.NET model means that the events are handled in the code-behind, you end up with the View handling events. This is not really in keeping with the MVC model we wanted to implement.

Model View Presenter


As a result of these ASP.NET language features, I discovered that Model View Presenter (MVP) was the best pattern to employ when using ASP.NET, as it separates the behavior of a presentation from the view whilst allowing the View to receive user events. See Martin Fowler's definition, and a good example implementation by Jeremy D. Miller. Basically, the MVP pattern has the ASP.NET page (including code behind) as the View, its has the Model behind a Facade, and the Presenter object acts as the go-between that gets events from the view and performs the necessary interactions with the Model, and then informs the View with the results. MVP also aids the unit testing of the page logic, which is very cumbersome to attempt using NUnit when you are relying on ASP.NET runtime infrastructure to hook the page together.

No comments: