MVC 5: Understanding the MVC Pattern

Hesam Seyed Mousavi, October 31, 2014

Source: I.NET Pro
The term Model-View-Controller has been in use since the late 1970s and arose from the Smalltalk project at Xerox PARC where it was conceived as a way to organize early GUI applications. Some of the details of the original MVC pattern was tied to Smalltalk-specific concepts, such as screens and tools, but the broader concepts are still applicable to applications—and are especially well-suited to web applications.

Interactions with an MVC application follow a natural cycle of user actions and view updates, where the view is assumed to be stateless. This fits nicely with the HTTP requests and responses that underpin a web application.

Further, the MVC pattern enforces a separation of concerns—the domain model and controller logic are decoupled from the user interface, which means that an MVC application will be split into at least three pieces:
• Models, which contain or represent the data that users work with. These can be simple view models, which just represent data being transferred between views and controllers; or they can be domain models, which contain the data in a business domain as well as the operations, transformations, and rules for manipulating that data.
• Views, which are used to render some part of the model as a user interface.
• Controllers, which process incoming requests, perform operations on the model, and select views to render to the user.

In the MVC framework, controllers are C# classes derived from the System.Web.Mvc.Controller class. Each public method in a class derived from Controller is an action method, which is associated with a URL defined through the ASP.NET routing system. When a request is sent to the URL associated with an action method, the statements in the controller class are executed in order to perform some operation on the domain model and then select a view to display to the client. Figure 1 shows the interactions between the controller, model, and view.

Hesam_Seyed_Mousavi_MVC application

The ASP.NET MVC framework use a view engine, which is the component responsible for rendering a view to generate a response for the browser. The view engine for the MVC framework is called Razor, and you’ll see examples of Razor markup throughout this article. If you don’t like Razor, then you can select one of the many third-party view engines that are available (although I won’t be doing so in this article, not least because I find Razor to be robust and easy to work with).

Models are the definition of the universe your application works in. In a banking application, for example, the model represents everything in the bank that the application supports, such as accounts, the general ledger, and credit limits for customers—as well as the operations that can be used to manipulate the data in the model, such as depositing funds and making withdrawals from the accounts. The model is also responsible for preserving the overall state and consistency of the data—for example, making sure that all transactions are added to the ledger and that a client doesn’t withdraw more money than he is entitled to or more money than the bank has.

Models are also defined by what they are not responsible for: Models don’t deal with rendering UIs or processing requests; those are the responsibilities of views and controllers. Views contain the logic required to display elements of the model to the user—and nothing more. They have no direct awareness of the model and do not directly communicate with the model in any way. Controllers are the bridge between views and the model; requests come in from the client and are serviced by the controller, which selects an appropriate view to show the user and, if required, an appropriate operation to perform on the model.

The MVC framework doesn’t apply any constraints on the implementation of your domain model. You can create a model using regular C# objects and implement persistence using any of the databases, object-relational mapping frameworks, or other data tools supported by .NET.

Understanding the Benefits of the MVC Pattern
Each piece of the MVC architecture is well-defined and self-contained—this is the separation of concerns. The logic that manipulates the data in the model is contained only in the model; the logic that displays data is only in the view, and the code that handles user requests and input is contained only in the controller. This separation is at the heart of the benefits imparted by the MVC pattern—and by implication—the MVC framework.

The first benefit is scale, not in terms of how many users a web application can support but in terms of how complex it can be. Technologies such as Web Forms can be used to build complex applications, of course, but doing so requires detailed planning and attention to detail, and many projects end up as a morass of code that duplicates functionality and markup in multiple places, making extending or fixing the application difficult. It is possible to get into the same kind of mess with the MVC framework, but only by ignoring the MVC pattern. Most developers produce MVC projects that can scale in complexity without much difficulty and that are easy to maintain and extend (and if you do find yourself in a mess, the separation of concerns in an MVC framework application makes it easier to refactor the application back onto a stable footing).

The second benefit is unit testing. The module nature of the MVC framework makes it easy to perform unit testing, aided by the testing support provided by Visual Studio (although many other testing toolkits are available). The third benefit is flexibility. The separation of concerns makes it relatively easy to respond to changes in requirements throughout the life of the application. This is a hard benefit to quantify and comes in part from the MVC pattern and in part from the convention-over-configuration approach that the MVC framework has adopted, but once the fundamental pieces of an application have been developed, it is a simple task to modify or rearrange them to respond to requests in new ways.

Source: I.NET Pro