The Model-View-Controller (MVC) paradigm of programming is one that is often misused by most developers because it is simply the least understood. When reading tutorials on MVC principles most developers will launch right into the code, which is easy to follow for the purpose of the tutorial. But when those same users try and do it themselves, they find out that it’s a lot harder than it seems. This post aims to correct that by explaining the principles behind the MVC framework and the pro’s and con’s of using it.
In web development, every page will have it’s own Model, View and Controller. This is to ensure that only the information you are requesting is loaded. A lot of those new to the MVC approach will attempt to create a master controller which will then delegate this information to each Model as requested. In MVC, this approach doesn’t quite work. By creating separate entities for each requested page you will find that not only is it easier to maintain and update, but that MVC isn’t that hard to understand at all.
The Big Picture
The easiest way to understand MVC is to step back and look at the whole picture in terms of real-life. In this example, our Controller is going to be the Librarian, the Model is going to be the Library Catalogue and the View is going to be a Book. A user will come up to the Librarian and say “Hey, do you have Book XYZ?” The Librarian of course has no idea. It’s not their job to know where each Book is, but simply to know where to find the information that you are requesting. Regardless of what you are requesting the Librarian will look through a Library Catalogue, but they may look in different kinds of Catalogues. For example, if you say “Hey, do you have the Horror Book XYZ?” they can ignore every other category except Horror. Likewise if you say “Hey, do you have the Romance Book XYZ?” they can ignore every other category except Romance.
The Pieces of the Puzzle – The Controller
The Controller the is the primary building block of an MVC system. Everything you build is managed by the Controller (it Controls see? Programmers love these little word games). The Controller figures out what the user is trying to do and accordingly it goes through the appropriate Model and returns those results to the appropriate View. You can think of the Controller as a messenger. Basically when the user visits a page they are saying “I would like to see the [Gallery] page”. The Gallery Controller will see this and go right over to the GalleryModel and say “The user has requested this information”. It then waits for GalleryModel to respond, and then it takes those results and runs over to GalleryView and goes “Pretty this up”. It then shows you the prettied-up version.
The Model
The Model is also known as your Data Manipulation layer. This should contain functions that interface with the database. Insertion, Updating and Deletion should all occur here, with the results of each passed back to the caller. This centralizes all your DB calls to a single file for a single controller. In this way you know that modifying your “Gallery” table means only modifying your GalleryModel and GalleryView. It doesn’t seem like a big issue to inter-twine your database manipulation and controller at this stage simply because it isn’t. Of course you can integrate your Model directly with the Controller, but by segmenting these you can ensure a much easier re-use of code. Think about it this way – a gallery model can be copied and modified a little to turn it into a blog model. Since the Model doesn’t care about what to DO with the fields, you just need to update what fields it SHOULD be dealing with.
The View
The View is the easiest piece to explain. It simply acts as a display mechanism. It accepts some values from the Controller, mixes it with HTML and spits the result back to the controller. Think of it is a node-based theme engine. For example, you could have a function in your GalleryView that just accepted the URL of a thumbnail and added some HTML which, when styled, made it resemble a Polariod. At a later point in time, if you want to change this, modifying this single function will ensure that everything is changed uniformly.
The Big Picture – Now with the right words
So now we can revisit our Librarian and ask for a new book. We ask the LibraryController for “Horror book XYZ”. The LibraryController invokes the LibraryModel and executes the findBook() function passing it the genre (horror) and book name (XYZ). The LibraryModel executes a quick Database Query to figure out the results. Just so happens there are 5 books in that genre that contain XYZ (XYZ, WXYZ, AXYZ, XYZZ, XXYZ). It passes the result set BACK to LibraryController. LibraryControlled takes the result set and invokes LibraryView, calling the formatBookList() function using the result set as the argument. formatBookList() adds some HTML mockup to each entry and makes everything look good and then passes the HTML back to LibraryController. LibraryController shows you the result.
Variations
Some descriptions of MVC will modify it so that the Controller ignores the view and instead the Model is what passes the data to the View. Either way still conforms with MVC standards, which really just involve separting everything.
Advanced Concepts
Routers
When dealing with server-side languages on the web we have to remember that things don’t work the same as in a desktop environment. Event-driven programming may work fine for C# and Java, but doesn’t work the same way for PHP. In PHP, our equivalent fo Event-driven programming would be URL-based programming. An “event” as far as PHP is concerned, is the user trying to visit a page. This page should trigger some kind of action. In most MVC frameworks (all I would think), you get something called a “Router”. This Router class is essentially a way of registering URLS to certain Controllers. For example visiting www.example.com/gallery/view/48 would cause the Router (or page that invokes the Router) to invoke the GalleryController and make a call to the view() function passing it 48 as an argument. In this way they abstract away explicitly invoking galleryies and can have a single index.php page which invokes the Router and makes the calls as necessary.
Multiple Inheritance
While PHP doesn’t allow for Multiple inheritance (ie GalleryController extends c1, c2, c3) it does allow for cascading inheritance (GalleryController extends c3; c3 extends c2; c2 extends c1; and now GalleryController can do everything c1, c2 and c3 can). Because of this we can actually speed up our Model/Controller creation by extending a singple base Model or Controller class. These classes would ideally have common functions that all Models or Controllers could potentially need at some point. One example would be to force all Models to inherit from BaseModel which could be a custom created Database Manipulation functions that all Models would need.