Cargo Cult MVC

Wikipedia describes “cargo cult programming” as “a style of computer programming characterized by the ritual inclusion of code or program structure that serve no real purpose”.

I believe that MVC web frameworks have essentially forced a cargo cult mentality on programmers.

The Problem

Pretty much all MVC web frameworks use the notion of a front controller.

The front controller has the responsibility of handling every web request, and then gives that request to the proper controller.

For example, in CakePHP the default configuration is to use convention names to choose routes. Suppose I had the following piece of code

The front controller for CakePHP would automatically associate PostController::index() to the url /posts/index

The front controller’s strategies for dispatching work to controllers is pretty arbitrary. However, the most typical strategies are to use xml file configuration, annotations, naming conventions, or fluent interfaces.

Typically, we try to organize our code around use cases because it is a technique that we know promotes loose coupling and high cohesion. A use case in this context is any single useful thing the system must do. For example, “edit an article” would be a use case for a blogging system.

However, there is no guarantee that a single url will always be associated with a single use case. Consider the case of a web search form. Imagine that we have a url of product/search?q=some_search_term. That web request would then be passed to a controller like the following

The problem is that the controller actually has 5 use cases:

  • show zero results
  • show one result
  • show many results
  • show lots of results
  • opps

To understand why, consider how an average person would expect the system to respond.

  • Case Zero: If there were no results for a search then I would want to see a dedicated page telling me that there were no results.
  • Case One: If there was only one result then I would want the system to immediately show me the details of that single item.
  • Case Many: If there were many results that could fit on a single page then I would just like to see a listing of those results so that I can choose to drill down into a specific item.
  • Case Lots: If there were too many results to list on a single page then I would want to see some sort of pagination.
  • Case Opps: If something bad happened which prevented the system from responding to my request then I would want the page to tell me that.

Rather than being MVC, we know have MVVVVVC. This isn’t exactly what we want from an engineering perspective, but it is what we were forced to do in order to satisfy the business requirement.

We can work around that situation pretty easily with the proper use of design patterns. For example, we would simplify the controller logic with the use of the strategy pattern. However, in so doing we are no longer using the MVC paradigm. It would be “Model StrategyContext View Controller”.

Not all cases are that simple to work around, though. Consider the situation where you have different roles for a system, and that each roles is allowed to view different things, and perform different work. Now consider that you wanted to expose that kind of functionality through a single url. How painful would that code be?

The Solution

Do not treat MVC like it is a silver bullet solution. There are plenty of alternative architectures out there. Google the following terms to see

  • Hexagonal Architecture (aka ports and adaptors)
  • Onion Architecture
  • Clean Architecture
  • Lean Architecture
  • DCI Architecture
  • CQRS
  • Naked Objects

Conclusion

Everything has it’s time and place. It is your job as a developer to think. Blind adherence to a framework will not save you.

I should also point out that MVC architectures themselves are not bad. How we use it is bad. MVC architectures definitely had their usefulness, and they probably still do.

For example, MVC architectures are really good at doing very simple data entry system because a single use case can actually fit into a url.

Consider the following mappings between a URL and a Use Case

URL Use Case
/article/create Create
/article/:id: Read
/article/:id:/edit Update
/article/:id:/delete Delete

In this case, each url maps very well to a single use case; so, MVC would probably be a really good choice to power an app like this.

However, in my opinion, most systems will not be this simple. Most systems are now very sophisticated and if they are not sophisticated then they eventually will evolve to something that is. You might as well architect your system with something that you know can help you evolve.

Javascript Exception Handling With the Visitor Pattern

I recently help a friend fix some convoluted javascript exception handling code, and I thought that the javascript community might find it useful.

The Problem

Javascript does not allow multiple catch clauses based on exception type. In programming languages like Java, we are allowed to write code like this

However, javascript only allows a single catch clause; so, exception handling code is often written like the following

The above code leaves much to be desired. This is what I wanted to improve

The Solution

We can use the visitor pattern to dynamically choose the right algorithm based on the events type.

This refactor makes the code easier to read and maintain.

For example, in the previous implementation each if statement would increase the cyclomatic complexity by 1. The refactor has made the cyclomatic complexity of the catch clause 1 for any number of exceptions.

Implementation

The solutions we created needs to be supported by code specifically designed to facilitate the visitor pattern.

As a first step, we we create a set of modules that inherit from the built-in Error object. The following is an example of how we implement the inheritance mechanism using native javascript:

Note: This is just one way to implement inheritance in javascript. If the following code looks unfamiliar to you then I suggest that you spend some time studying the internals of how javascript supports polymorphism.

The function addExceptionHandlingVisitor acts as a decorator for our custom Errors. It’s purpose is to allow each error module to visit an error handler. It does this by attaching a visit function to any module that is passed to it.

In the code above, The visit function expect an exception handling module (i.e. context). The context variable is expected to have two function: test and handle. The test function is expected to inform the visitor whether or not it is a handler for the error, and the handle function is expected to actually handle the error.

Consider the following implementations of handlers for DuplicateUsernameError and CreditCardRejectedError.

Note: We could refactor this to have an inheritance hierarchy with reusable code, but I don’t believe that their would be much benefit in going to that effort.

Complete Code

A working example is also located on my jsfiddle account:

http://jsfiddle.net/supalogix/DgL7u/

Conclusion

I am not making any claims that this is the best way to handle exception handling in javascript. However, you should not allow any piece of your code be written with complicated if-else statements.

If you find yourself writing a lot of conditional logic in single place then that should set an alarm in your head that reminds you to simplify your code with the use of polymorphism. Simplifying complicated conditional logic like nested if-else statements is exactly why polymorphism was invented.

Just remember that javascript is not java, c++, or c#. javascript is javascript. It has it’s own form of polymorphism, and you should know how to use it properly.