Recently we were asked why our codes didn't use any MVC patterns or frameworks. We are glad that someone is paying attention to technical details. And, yes, we confirm that we don't really use MVC frameworks, or MVC in any obvious form. Instead, we use an architecture called Loader-Container-Handler-Handler, or LCHH.
Comparing LCHH with MVC is like comparing apples to oranges. LCHH is an implementation-specific architecture, and Model-View-Controller (MVC) is a more abstract design pattern. One can implement LCHH using a MVC framework (but why would you when you don't have to?); and LCHH is subtly, yet efficiently realising MVC, which we'll see later in this article.
Many application frameworks today organise code by forcing the programmers to implement models, views and controllers separately, hoping to deliver the benefits of a MVC design. Comparing to other design patterns, MVC has shown promises and is therefore highly praised by the programming community.
The issue with MVC is that it's kind of, for the lack of better word, magical. In order to build software by dealing with data and presentation independently, one relies on a underlying framework. After all, MVC is a high level concept and web applications, which run on the stateless HTTP protocol, certainly do not use the Model-View-Controller pattern, or any patterns for that matter.
The LCHH architecture can be either viewed as a specific implementation of MVC, or an alternative to the MVC pattern altogether. Before we dive into the benefits of LCHH, let's look at some of the common issues of MVC frameworks.
First of all models and views are not truly separate. In theory, the model could contain all the information about a subject of concern, and such information is passed onto a view for selective rendering. However, this is just plain inefficient. In practice, the model is mindful of the view, providing just enough data; and this defeats the purpose of a pure separation.
The role of Controllers in MVC is also often misunderstood. A controller is not the broker between Model and View. it should interface the user and the application. However, due to the stateless of the web, the Controller is called upon to glue together Models and Views. Most of the business logic is implemented in controllers, and some in models and some even in views. it's messy isn't it?
MVC has performance overhead. Like many other paradigms, the benefits of the MVC pattern come at a cost. Programmers want a unified design process and separation of concerns. To a machine, these expectations are unnatural and pointless.
Frameworks were created so that things just magically happen. What is magic? Magic is when you put an apple in a hat, and an apple pie comes out (ovens do that too, but you have to make the pie yourself). Magic is a black box, hidden cost, and hence overhead.
An argument we often hear is that performance hit can be justified by the gain in productivity. Well, MVC also has programming overhead. There has been extensive debate over what constitutes a Model, and how to best use the Controller so that the Views are not littered. The development process is riddled with ambiguity. As mentioned earlier, the Model and View should be mindful of each other, and this requires the programmer to hop back and forth between the model and view code. Of course, he can always populate the model object with every piece information but that's just lazy programming.
Another misconception is that MVC automatically affords the labour separation between "coders" and "designers", and between "backend-" and "front-end" developers. In our development pipeline we also separate coders and designers. The designers are aware of the limitations of devices and browsers, and produce mock-ups for the coders to implement. The coders are spared to think about how the application should look like, yet they weigh in on the flow and the layout of the user interface. This is a healthy kind of collaboration; the focus is on complementing the skill sets of coders and designers, not separating them. Some shops take the concept the wrong way. They expect the coders to be able to manipulate the graphics, and worse, the designers to code the "view" component in a typical MVC application.
Now that we've talked enough about MVC, let's look at an alternative paradigm, namely Loader-Controller-Handler-Handler. The first handler is for the client, and the second for the server-side events.
How does LCHH work?
LCHH has 4 components that corresponds to either server or client side of a web application. They are
Loader (a DIV element with an ID), Content (HTML content and event triggers), Client-side Handlers (JavaScript functions that handle clicks and other user interactions), Server-side Handlers (scripts that process AJAX requests and returns updated contents that's injected into the loader). The following diagram illustrates the flow of LCHH.
Benefits of LCHH
LCHH doesn't need a framework to run. as long as the 4 components are implemented, information naturally flows from one to another. This means no programming overhead or performance degradation.
Also, since LCHH creates a feedback loop between the end users and the database storage, the states are kept in the database; LCHH components are stateless, so applications that use LCHH are highly scalable. This feedback loop coincides with the life cycle of an HTTP request, making implementation and debugging straightforward. The usage path, code execution path and page rendering path are all the in sync.
With LCHH, the coding work is divided up differently among programmers. There is no front- and back-end designation. Instead, each programmer takes care of a set of modules from start to finish. Traditionally there is a great divide between the front-end developer, who's knowledgeable of all the user interactions but has no idea how the data plumbing works, and conversely, the backend developers are expected to know all the programming logic. LCHH, on the other hand, uses an event-driven, de-centralized approach, requiring a programmer to know his own parts of loader layout, content, event triggers and server handlers. When this programmer finishes his work, the module that he's responsible for will be fully functional.
It's important to clarify that LCHH still respects the principle of model-view separation. It simply doesn't rigidly divide up the application layer into Model, View and Controller. In the context of a 3-tier architecture, the database is a model, and the rendered web page is the view. And the server-side code on the application layer acts as a controller, taking care of everything in-between.
In conclusion, we see the LCHH architecture as an effective alternative to MVC frameworks. It allows a more rapid and straightforward programming paradigm, better performance and code maintainability.