I was in a coding rut i.e the moment when you are implementing a new feature. You write little code and test it and write again and test it. You do it until you get the desired result.
I was thinking about all the ways a user can interact with my software. Writing code for all the possible user inputs. As soon as the user makes a ‘move’ the core logic behind the scenes responds and the user screen gets updated.
But this rut leads me to frustration and made me think about the way I was writing code. Meanwhile, a lesson from my earlier days of programming came to my mind.
“Thou shall separate logic from input/output”
So I write the separate code for input and logic. Did that make anything easier for me? Hmmmm I don’t know because I was again in the coding rut to the point of frustration.
I realized that I update the user interface as soon as there is a user input.
Do you recall anything? Do you remember the kindergarten block diagram of a computer?
There are three basic functions in a computer: 1) Input 2) processing 3) output. Computers take input, process that input and display the output to the user. A simple template that I realize after some frustration.
But this was not the only realization. There was another! Pondering upon the code I realize that I have implemented Model View Controller design pattern. There was a very simple template that I studied earlier but understand it deeply after some painful experience.
But wait, why I told you this story of my euphoria? Because I believe that all programmers need these feelings to clarify or deeply understand some programming concepts. No matter how many times you read them– you will only understand benefits when you feel it.
In this post, I will give you a template in the form of steps that can help you deeply understand MVC. I will also demonstrate the template with a simple example.
Why you need MVC?
How this MVC became so important that everybody is talking about it? Is it a modular approach? Is it easier to test? OR Is it just the current trend?
Whatever be the reason but remember that it will be asked in your job interviews. Interviews that you will give to get an exponential bump in your salary. So it is in your best interest to learn MVC.
Also, there is an easier way to learn MVC. Just go to YouTube and watch a walkthrough of implementing MVC on any platform. But you will be like million developers out there who are using MVC frameworks but don’t have the profound knowledge or don’t know the real philosophy of MVC.
But once you deeply understand the basics you can write your own MVC framework, learn other implementation fast, tweak/optimize any existing open-source MVC implementation and so more.
No. 1 Obstacle in the Path to Learning the MVC
Following is the No. 1 obstacle in the path:
Yes this figure is the No.1 distraction. I hate this diagram. Because it never helps anybody understands what is MVC. This will only help you understand what is there in the MVC and not why is there a MVC. But you will find this figure everywhere you try to learn MVC.
You can easily understand MVC if you take it step by step. The easiest way that I can describe MVC is in two steps. First is to learn the publisher-subscriber pattern and second step is to learn the strategy pattern.
Step 1: Understand the publisher-subscriber design pattern
The gist of the pattern is this: there are two entities in your code. One entity wants to know what’s happening with the other entity. It’s like entanglement if you are a fan of Quantum Physics. In programming, both of these entities are connected via a method call.
There are dedicated roles for these two entities. One is called the publisher or observable and the second is called the subscriber or observer.
As soon as there is a change in the publisher/observable the publisher notifies the subscriber. Now the subscriber pull the data from the publisher whenever it gets notified. Also, both publisher and subscribers are loosely coupled via a generic interface.
In the context of MVC, consider the model as the publisher and the view as the subscriber. As soon as the underlying model is updated the view gets notified by the model and then the view pulls the information from model and display that to the user.
Using this pattern, the model is not dependent upon the view and you can replace/change the view without worrying about the model.
Step 2: Understand the Strategy Pattern
The second important design pattern is the easiest one and that is the strategy design pattern. In strategy, an object can talk to any other object that is defined with a common interface.
For example:
Car object can talk to BrakeWithABS object or Brake object. Also, selection of objects can be decided at run-time. Both of these objects implement the same interface, therefore, the user can select any object at run-time and they are interchangeable. The beauty of polymorphism!
In MVC design pattern, a controller is implemented using the strategy pattern. There can be many controllers in an MVC application and anyone can be selected for processing user input at run-time.
One thing to keep in mind is that the user views the ‘view’ and interacts with the controller. All of the user actions are received by an appropriate controller and then controller calls the appropriate model objects.
How They All Work Together
In a typical MVC design pattern, the user of the software only views the ‘view’ or the front end. At the front end, a user interacts with the software. This interaction is captured by an appropriate or selected controller. Here the strategy pattern is in action.
The controller then calls the model object. Remember there is no pattern here. It’s just a simple call that exists between 2 objects.
Before both of these steps, the views are registered to the models. Based on the controller interaction the model gets updated and notifies all the views. Here the publisher-subscriber design pattern is in action.
In this manner, the complete chain of MVC is completed.
Let’s implement a super simple MVC in .Net Winform application. You can also download the complete example code here.
This is a .net WinForm application. You can see a rectangle panel which defines the boundary for the inner object. You can also see the four buttons which will move the inner object by one pixel in the direction you want.
This rectangle and the position of the object defines the model of the application. The object cannot move outside the bounds of a rectangle.
Following code shows the code of the model. Not that there are no Winform GUI components in the model code. Hence this model is portable and can be used with any other type of view.
Example Model Code:
class BoundaryModel : MVC_Simple.IBoundaryModel { List viewSubscriber = new List(); // initial position of object int topLeftX=0; int topLeftY=0; // Model Parameters. int objectWidth=100; int objectHeight=50; int panelWidth= 480; int panelHeigh=240; public void AddViewSubscriber(IView aView) { viewSubscriber.Add(aView); } // Notify all the subcribers when the model is changed.. private void NotifyAllSubscribers() { foreach (IView aView in viewSubscriber) { aView.mainModelUpdated(); } } public void moveRight() { if ((topLeftX + objectWidth) < panelWidth) { topLeftX += 1; NotifyAllSubscribers(); } else { // Raise the Exception } } public void MoveLeft() { if (topLeftX != 0) { topLeftX -= 1; NotifyAllSubscribers(); } else { // Raise the Exception Here. } } public void MoveUp() { if (topLeftY != 0) { topLeftY -= 1; NotifyAllSubscribers(); } else { // Raise the Exception Here. } } public void MoveDown() { if ((topLeftY + objectHeight) < panelHeigh) { topLeftY += 1; NotifyAllSubscribers(); } else { // Raise the Exception Here. } } // for pulling information from model public int GetUpperLeftY() { return this.topLeftY; } public int GetUpperLeftX() { return this.topLeftX; } } }
Note that this model class notifies all the subscribers whenever there is a change in the model.
Example View Code:
The view is simple. As soon as it gets notified it will fetch the updated model information.
public void mainModelUpdated(){ // THe observer is notified now it will pull the model state and update the view.. Point aPoint = new Point(mainModel.GetUpperLeftX(), mainModel.GetUpperLeftY()); this.movingObject.Location = aPoint; }
In the above code, you can see that several Winform GUI components are used. The view object is fetching the model information and updating it’s GUI components.
Here you can see the publisher-subscriber pattern in action.
Example Controller Code:
The user views the ‘view’ and interacts with the controller. This example contains one controller and one view. Following code shows that how the view delegates the user request to the controller:
// View Code private void btnRight_Click(object sender, EventArgs e) { mainController.MoveRight(); } private void btnUP_Click(object sender, EventArgs e) { mainController.MoveUP(); } private void btnDown_Click(object sender, EventArgs e) { mainController.MoveDown(); } private void btnLeft_Click(object sender, EventArgs e) { mainController.MoveLeft(); } //At the controller side the controller receives the user input and calls the model: public void MoveRight() { aModel.moveRight(); } public void MoveLeft() { aModel.MoveLeft(); } public void MoveUP() { aModel.MoveUp(); } public void MoveDown() { aModel.MoveDown(); }
But where is the Strategy Pattern?
Above example, contains one view and one controller. Therefore, you cannot see the strategy pattern in action.
How can you swap the controller at run-time based on the user input? To learn that, let’s do one exercise. In the above example application, the object in the panel move by one pixel in each direction. I want you to update the code and move the object 10 pixels on each command. Here is the desired screenshot:
You can write the multiple controllers for the same View and choose the controller based on the user selection. Try yourself and then compare with the solution code here.
The Real World MVC
Real World MVC is mostly related to the web. So can you use the example given above? No. Can you use the template? YES.
There are several variations of classic MVC implemented in different technologies. These variations are there to cater the needs for web applications.
For example, in a web application, a publisher-subscriber pattern cannot be implemented between the view (an HTML page) and the model (an object on the server). Hence there are slight variations made to the classic MVC pattern. One variation is called Model 2.
In Model2, most of the responsibility is given to the controller. Since it is written for the web, there sits a controller that deals with all input request ( HTTP request ) and respond with a View object. The Model 2 is also used inside in .Net MVC.
But, the strategy pattern remains intact. The controller is selected at run-time. Based on the user input a front controller or a router sends the input request to the desired controller. This controller then updates the model and returns the updated state. In a web app, the ‘view’ is simple and it just renders the returned model states on the screen.
There are several other variations that are inspired by MVC such as Model-View-Presenter (MVP) and Model-View-View-Model (MVVM) and they were adopted in different platforms.
Most of the Hard Work is Done for You!
Look at the example above and take a note how I created objects. It is in the main program.cs object. This is a decision that I took on the fly. But this will become the dependency as the project grows and the right approach is to create objects using creational design patterns.
This kind of small decisions and grunt work is done for you by a latest MVC web framework. For example, .Net MVC framework can do the following things for you
Validation: Input validation provided by the .Net MVC framework.
Routing: In the example above there is only one controller and one view whereas in .net MVC there are several controllers and they are accessed via routers. There are several methods for routing but the most flexible method is via regular expression.
Scripting Language: .Net provides Razer scripting language for accessing model data alongside the HTML.
And numerous other features.
So, any available framework provides additional features which make it unique but the basics are same as of our model.
Now you can use this model as the basic template and learn the implementation provided by professional frameworks by understanding the differences between this simple template and the latest version of any MVC framework.
Homework
I have discussed some of the features of .Net MVC model and show some differences with the classic MVC pattern. Another famous JavaScript framework for writing web application is NodeJS with AngularJS. Study and find out how to implement MVC in this framework and what are the differences when compared to the classic MVC template.
Amazing simple explanation! Thank you 😀
Great job!
An MCVE for MVC, very helpful!
Thanks for the appreciation AL.