If you've done any sort of web programming recently, you have probably heard about MVC.

MVC, which stands for "Model-View-Controller," is a particular design pattern which attempts to separate the logic of an application from its presentation. It is particularly popular with web programmers, although it can be applied to other areas of programming as well.

Until recently, I was pretty clueless about MVC. My only knowledge of the subject came from passing references to it found in various blog posts and podcasts. When I started planning out my new web project, I accidentally reinvented MVC in my attempts to keep my design relatively clean. When I was told how close I was to MVC, I decided to do a little more research into the subject, and this blog post is the result of that research.

What is MVC?

There are four main components to MVC: the eponymous models, views, and controllers, and something called a router, which is essentially another controller, but which I consider enough of a special case to warrant special mention.

Routers and Front Controllers

Front Controllers are the first entry point into your application. As explained in my previous post, Apache web servers can be configured to redirect all requests into a single file, usually called index.php. This index.php file would be the front controller for the application.

It is from this file that your application is bootstrapped, and configuration files are loaded. These configuration files can and should include definitions which map your directory tree to constant values in your application (using define() statements in PHP), so you can quickly and easily find files your need.

Once the application is prepped and ready to go, the router takes over and directs (routes) processing to specific controllers which are better suited to handle that particular form of request. In practice, a lot of the time this is simply a matter of extracting variables out of a URL to find a controller name (remember from last time that, by design, URLs often begin with a controller name), verifying it exists, then passing control to that router.

You may have noticed by now that front controllers and routers have some overlap in responsibility. I consider them to be the same thing, but some purists may want to separate routing capabilities into their own class, so I have tried to separate them a bit in this description.

Controllers

Controllers are essentially gatherers. They are the middle managers of your application. Their entire role is to know what is needed to fulfill a task, and who to ask for it. They aren't there to do any real work (a fact many people seem to miss, leading to an epidemic of "fat controllers"); they are there to facilitate the work of others.

When a request is passed to a controller from the router, the constructor for that controller will once again extract data out of the URL to determine which action is required. In the example "questions" controller example used in the last post, the questions controller would need to decide between the "ask" and "display" actions available to it based on the data in the URL.

Once a suitable action is identified, a method is called to execute that action. This method will have a grocery list of data it needs to collect, and it will use any number of specific models to get that data. When data is returned from a model, it gets stored in the controller (or potentially a special data repository object) for later use.

Once the controller has collected all the data it needs, it will determine how the data is meant to be displayed. For example, the same data could be output as an HTML page, an RSS feed, or an email. When the controller knows what sort of display is needed, it passes all the data to an object called a view which is responsible for rendering the data in the appropriate format.

Models

You may have taken a class in school which explained the fundamentals of object-oriented programming (OOP). In this class, your professor probably made a big deal about how this paradigm can be used to create software models of real world objects for your application to interact with. The models in MVC refer to exactly the sort of models your professor was talking about.

Models can take many forms. The most common examples given for models online tend to take the form of database abstraction, but that is just the tip of the iceberg. If you were creating a banking application, you could have a Mortgage class to give approval, determine rates, and calculate payments. This mortgage class would be a Model.

Essentially, all of your business logic, all of your database logic, and practically anything that doesn't deal directly with displaying information to the user would be considered a model.

Views

I've covered views a bit already as part of my explanations of models and controllers, but let's explain it again anyway.

Views are the interface between your application and the end user. They are the HTML displayed by a users web browser, the message received by the users email client, and the feed in your users RSS reader.

By the time a controller passes control of the application to a view, all of the heavy lifting has already been done. All of the data to be displayed to a user is wrapped up in a shiny package and presented to the view with a bow on top. In fact, some people prefer that views aren't objects at all, but rather simple scripts with placeholders into which precomputed values are dumped. I happen to take a slightly different approach, and think that views can and should contain methods of their own. These methods, quite obviously, should only contain presentation logic, such as choosing between displaying a logged in users information, or a generic "log in or sign up" type of message. By separating this sort of logic out into methods, the main template of a view becomes that much cleaner.

Conclusion

Before I looked into MVC in any depth, I was convinced that it was a needlessly complicated framework that I would spend weeks trying to wrap my mind around. In the end, it only took me an hour or two one morning to get everything sorted out.

I encourage you, if you're starting your first MVC project, to take the time to build your own mini framework for a simple project you want to build. While premade frameworks like CodeIgniter are great, I think it's always a good idea to try to roll your own at least once. By forcing yourself to immerse yourself in the details, you will have a better understanding of what's going on should you decide to use an open source framework later on.

Happy coding!