Thursday, October 15, 2009

MVC, why is it so important and why n-tier matters:

If you've been programming for a while, you've undoubtedly have come across the Model-View-Controller (MVC) design pattern. When I started programming my code started out as just one long procedural call, the "everything in the main function" design pattern. As I got better with programming I started breaking logic into different functions and calling the functions. Eventually, I got to Object Oriented Programing (OOP) and began the path of looking at programming not as a bunch of steps that need to take place to reach a goal; but instead as distinct ideas and concepts that put together, made a program.

The MVC design pattern was developed to give developers a way of looking at a problem and separating common areas of a program. Basically, a program has to deal with the end-user and a database. We could easily design a monolithic program that did the task, but if something changes in the database, then we need to modify all of our code (or at the very least hunt down the section in our code that deals with the database) to adapt to the change. Logically speaking, it wasn't long until people started to understand that the user interface should be a separate body of code from the part that deals with the database. As user interfaces got more and more complex, the logic that handles validation and talking to the database module had to be separated too. Thus was born the MVC design pattern. In essence, gurus would preach the divide and conqueror technique of MVC to new developers in hopes that they would start their programs in the vein of MVC. This way as the program evolved, it evolved with ease.

However, there is one fall down to MVC. It assumes that all things are on the same machine. When we start connecting to a remote database to update our view, we start getting into handling SQL statements, exceptions, invalid return values, and many more issues (does NULL mean that the line should be blank or does it mean invalid?). The view is not the place to handle this type of code, or at least if you want to keep things simple. Thus, people holding to the MVC design pattern have created ways of wrapping database connections into convenient APIs that handle the mess, so that you can devote more time to making a good user interface.

It's a nice thought, but it only goes so far. Just pick up a book on MySQL and PHP and notice how many times they suggest that you just ignore exceptions. Eventually, way back in the day don't let me make you think that this is a new development, it was understood that one machine just couldn't run everything (contrary to IBM's claims), and thus we embarked on a mission to find a way to make a program run on multiple machines. Enter multi-tier design patterns.

At first, people used messaging systems to communicate between different machines. Think of it as Bob's copy of program A is running on Server A, Jane's copy of program A in running on Server B, and so on. Server A and Server B talk to each other to keep data in sync using a messaging protocol. This was an alright solution, but it really didn't get far from the MVC way of looking at things. It was also a waste of resources, the View didn't use as much resources as say the Controller; the Model used the most disk space; the View was limited to the interface capabilities of the machine holding the Model and the Controller. Basically, if your database had eaten all of your hard drive, you upgraded the drives; controller eating all your memory, you added more. It would have been better to place the Model on a machine with tons of hard disk space, the Controller on the fastest CPU, and the View on a system that supported familiar GUI elements.

Multi-tier design patterns were developed to allow each layer in the tier (Presentation, Logic, and Data) to run on different machines. Some used proprietary protocols to achieve this (SNA comes to mind). With the advent of the Internet, the standardization of TCP/IP as the protocol of choice, Microsoft bringing open network connectivity (I know, who would have thought), and the desire for things to be less single vendor and more heterogeneous, new methods would need to be put into place to actually implement multi-tier design patterns.

This is where multi-tier underwent its first redesign. Now instead of assuming that the protocol would be packed with the vendor, multi-tier patterns had to abstract protocols altogether; in essence the developer shouldn't have to worry about the protocol, as long as the program can see the server everything should work. While we haven't gotten away from the idea that a program is tied to a protocol (Web browsers still assume TCP/IP as the transport), we have made progress (Web browsers can used IPv4 or IPv6). So it's important to remember that multi-tier is still protocol dependent, just now you don't have to worry about directly working with the protocol (unless you really want to!?).

This redesign is what gives us the model that we all know and love. It breaks the way an application works into three parts. Presentation, Logic, and Data. At face value it looks a lot like MVC, and to an extent it is. However, in a multi-tier application the Presentation is assumed to never talk to the Data, all things must pass through the Logic layer. Where as in MVC, the Controller provides input to the Model, and the view gets the output of the Model. This is the fundamental difference between the two.

In MVC your View must deal with the data straight from the Model. In multi-tiered applications the Logic formats the Data into something that can be Presented.

In MVC, your web designers must know what kind of assumptions should be taken on data from the data source and how to issue the commands to get that data.
In Multi-tiered applications, the Logic handles all of this, your web developers simply access the properties of you logic (much better to write something like #{shoppingCart.orderNumber} versus SELECT ORDERNUMB FROM ORDERS WHERE SHOPPINGCART='cartnumber';).

All in all, multi-tiered design patterns have been developed to make use of multiple machines, abstract protocols from developers, and allow specialty developers to concentrate better on the task at hand. I know that some people still have the notion of what three and four tier development was like in the 60's, 70's, and 80's (which wasn't good and took long amounts of time to deploy) but the methods and tools have been refined to a point to make multi-tier more like Rapid Application Development (RAD) software. Simply put, MVC is an easier model to work within, but Multi-tier is continuing to keep the pressure on MVC as an easy model to develop within. Multi-tier isn't like it was back in the day, it has mature enough to be seriously considered before you begin your next enterprise application.

No comments: