MVC (model-view-controller) is an architectural pattern. This pattern is commonly used in web applications and in developing powerful user interfaces. Trygve Reenskaug first described MVC in 1979 in a paper titled “Applications programming in Smalltalk-80TM: How to use Model-View-Controller,” which was written before the existence of the World Wide Web. So, at that time, there was no concept of web applications. But modern-day applications are an adaptation of that original concept. Instead of treating it a true design pattern, some developers prefer to say this an “MVC architecture.”
Wikipedia defines it as follows.
Model-view-controller (MVC) is an architectural pattern commonly used for developing user interfaces that divides an application into three interconnected parts. This is done to separate internal representations of information from the way information is presented to and accepted by the user. The MVC design pattern decouples these major components allowing for efficient code reuse and parallel development. (https://en.wikipedia.org/wiki/Model-view-controller)
My favorite description of MVC comes from Connelly Barnes, who said,
An easy way to understand MVC: the model is the data, the view is the window on the screen, and the controller is the glue between the two. (http://wiki.c2.com/?ModelViewController)
Concept
Using this pattern, you separate the user interface logic from the business logic and decouple the major components in such a way that those can be reused efficiently. This approach promotes parallel development.
From the definition, it is apparent that the pattern consists of these major components: model, view, and controller. The controller is placed between the view and model in such a way that they can communicate with each other only through the controller. This model separates the mechanism for how the data is displayed from the mechanism for how the data is manipulated. Figure 26-1 shows the MVC pattern.
Key Points to Remember
These are brief descriptions of the key components in this pattern.
View represents the final output. It can also accept user input. It is a presentation layer, and you can think of it as a graphical user interface (GUI). You can design it with various technologies. For example, in a .NET application, you can use HTML, CSS, WPF, and so on, and for a Java application, you can use AWT, Swing, JSF, JavaFX, and so forth.
The model manages the data and business logic, and it acts as the actual brain of your application. It manages the data and business logic. It knows how to store, manage, or manipulate the data and handle the requests that come from the controller. But this component is separated from the view component. A typical example is a database, a file system, or a similar kind of storage. It can be designed with Oracle, SQL Server, DB2, Hadoop, MySQL, and so on.
The controller is the intermediary. It accepts a user’s input from the view component and passes the request to the model. When it gets a response from the model, it passes the data to a view. It can be designed with C# .NET, ASP.NET, VB.NET, Core Java, JSP, Servlets, PHP, Ruby, Python, and so on.
You may notice varying implementations in different applications. Here are some examples.
You can have multiple views.
Views can pass runtime values (for example, using JavaScript) to controllers.
Your controller can validate the user’s input.
Your controller can receive input in various ways. For example, it can get input from a web request via a URL, or input can be passed by clicking a Submit button on a form.
In some applications, you may notice that the model can update the view component.
In short, you need to use this pattern to support your own need. Figures 26-2, 26-3, and 26-4 show known variations of an MVC architecture.
Consider our Template Method pattern’s real-life example. But this time, let’s interpret it differently. I said that in a restaurant, based on customer input, a chef adjusts the taste and makes the final dish. But you know that the customers do not place their orders directly with the chef. The customers see the menu card (View), may consult with the waiter/waitress, and then place the order. The waiter passes the order slip to the chef who gathers the required materials from the restaurant’s kitchen (similar to storehouses or, computer databases). Once prepared, the waiter carries the plate to the customer’s table. So, you can consider the role of a waiter as the controller, the chefs in the kitchen as the model, and the food preparation materials as the data.
Computer-World Example
Many web programming frameworks use the concept of the MVC framework. Typical examples include Django, Ruby on Rails, ASP.NET, and so on. A typical ASP.NET MVC project can have the following view shown in Figure 26-5.
Points to Note
Different technologies follow different structures, so you don't need a folder structure with the strict naming convention shown in Figure 26-5.
Implementation
For simplicity and to match our theory, I also divided the upcoming implementation into three major parts: model, view, and controller. Once you note the Solution Explorer view, you can identify the separate folders created to accomplish this task. Here are some important points.
IModel, IView, and IController are three interfaces that are implemented by the concrete classes EmployeeModel, ConsoleView, and EmployeeController, respectively. Seeing these names, you can assume that these are representatives of the model, view, and controller layers of our MVC architecture.
In this application, the requirement is very simple. Some employees need to register on an application. Initially, the application has three different registered employees: Amit, Jon, and Sam. These employees have ID’s as E1, E2, and E3. So, you see the following constructor:
At any point in time, you should be able to see the enrolled employees in the system. In the client code, you invoke DisplayEnrolledEmployees() on a Controller object as follows:
controller.DisplayEnrolledEmployees();
Then the controller passes the call to view layer as follows:
view.ShowEnrolledEmployees(enrolledEmployees);
And you see that a concrete implementor of View Interface (ConsoleView.cs) describes the method as follows:
public void ShowEnrolledEmployees (List<Employee> enrolledEmployees)
{
Console.WriteLine("
***This is a console view of currently enrolled employees.*** ");
foreach (Employee emp in enrolledEmployees)
{
Console.WriteLine(emp);
}
Console.WriteLine("---------------------");
}
You can add a new employee or delete an employee from the registered employees list. The AddEmployeeToModel(Employee employee) and RemoveEmployeeFromModel(string employeeIdToRemove) methods are used for this purpose. Let’s look at the method signature of RemoveEmployeeFromModel(...). To delete an employee, you need to supply the employee ID (which is nothing more than a string). But if the employee ID is not found, the application ignores this delete request.
A simple check is added in the Employee class to ensure that you are not adding an employee with the same ID repeatedly in the application.
Now go through the implementation. Yes, it’s big, but when you analyze it part by part with the help of the previous bullet points and the supporting diagrams, you should not face any difficulties with understanding the code. You can also consider the comments for your immediate reference.
Points to Note
Typically, you want to use MVC with technologies that offer built-in support and perform much of the groundwork. For example, when you use ASP.NET (or a similar technology) to implement the MVC pattern because you have a lot of built-in support. In these cases, you need to learn the new terminologies.
Throughout this book, I use console applications for design pattern implementations. Let’s continue to use the same for the upcoming implementation, because our focus is only on MVC architecture.
IController controller = new EmployeeController(model, view);
controller.DisplayEnrolledEmployees();
// Add an employee
Employee empToAdd = new Employee("Kevin", "E4");
controller.AddEmployee(empToAdd);
// Printing the current details
controller.DisplayEnrolledEmployees();
// Remove an existing employee using the employee id.
controller.RemoveEmployee("E2");
// Printing the current details
controller.DisplayEnrolledEmployees();
/* Cannot remove an employee who does not belong to the list.*/
controller.RemoveEmployee("E5");
// Printing the current details
controller.DisplayEnrolledEmployees();
// Avoiding a duplicate entry
controller.AddEmployee(empToAdd);
// Printing the current details
controller.DisplayEnrolledEmployees();
/* This segment is added to discuss a question in "Q&A Session" and initially commented out. */
// view = new MobileDeviceView();
// controller = new EmployeeController(model, view);
// controller.DisplayEnrolledEmployees();
Console.ReadKey();
}
}
}
Output
Here is the output.
***MVC architecture Demo***
***This is a console view of currently enrolled employees.***
Amit is enrolled with id : E1.
John is enrolled with id : E2.
Sam is enrolled with id : E3.
---------------------
Trying to add an employee to the registered list.The employee name is Kevin and id is E4.
Kevin is enrolled with id : E4. [added recently.]
***This is a console view of currently enrolled employees.***
Amit is enrolled with id : E1.
John is enrolled with id : E2.
Sam is enrolled with id : E3.
Kevin is enrolled with id : E4.
---------------------
Trying to remove an employee from the registered list.The employee id is E2.
Employee Found.John has id: E2.
Removing this employee.
***This is a console view of currently enrolled employees.***
Amit is enrolled with id : E1.
Sam is enrolled with id : E3.
Kevin is enrolled with id : E4.
---------------------
Trying to remove an employee from the registered list.The employee id is E5.
At present, there is no employee with id E5.Ignoring this request.
***This is a console view of currently enrolled employees.***
Amit is enrolled with id : E1.
Sam is enrolled with id : E3.
Kevin is enrolled with id : E4.
---------------------
Trying to add an employee to the registered list.The employee name is Kevin and id is E4.
This employee is already added in the registered list.So, ignoring the request of addition.
***This is a console view of currently enrolled employees.***
Amit is enrolled with id : E1.
Sam is enrolled with id : E3.
Kevin is enrolled with id : E4.
---------------------
Q&A Session
26.1 Suppose that you have a programmer, a DBA, and a graphic designer. Can you predict their roles in an MVC architecture?
The graphic designer designs the view layer, the DBA creates the model, and the programmer works to make an intelligent controller.
26.2 What are the key advantages of using the MVC design pattern?
Some important advantages are as follows.
High cohesion and low coupling are the benefits of MVC. You have probably noticed that tight coupling between the model and the view is easily removed in this pattern. So, the application can be easily extendable and reusable.
The pattern supports parallel development.
You can also accommodate multiple runtime views.
26.3 What are the challenges associated with the MVC pattern?
Here are some challenges.
It requires highly skilled personnel.
For a tiny application, it may not be suitable.
Developers may need to be familiar with multiple languages, platforms, and technologies.
Multi-artifact consistency is a big concern because you are separating the overall project into three major parts.
26.4 Can you provide multiple views in this implementation?
Sure. Let’s add a new shorter view called MobileDeviceView in the application. Let’s add this class inside the View folder as follows.
using System;
using System.Collections.Generic;
using MVCPattern.Model;
namespace MVCPattern.View
{
public class MobileDeviceView:IView
{
public void ShowEnrolledEmployees(List<Employee> enrolledEmployees)
{
Console.WriteLine("
+++This is a mobile device view of currently enrolled employees.+++ ");