There was an interesting exchange of ideas I witnessed today. The crux of the issue was someone trying to understand the benefits of the Model View Controller (MVC) pattern as socialized by Microsoft. Having some interest in the subject, I watched it grow from a comparison with Event Driven Architecture (a complete misnomer) to contrasting with Model View Presenter (a new flavor of old idea), to just plain batting around the technical merits of various implementations of these common concepts. As one person after another jumped on the band-wagon, virtually everyone had something insightful and technical to say. But none of them brought it back to the business problems. This troubled me as it was indicative of the way we forget that we are in the business of software development. Not just doing software development. Here was my contribution:
On many systems we see that there are really two types of logic often treated as the same while they are very different. The first type are UI rules which I’ve seen loosely defined as how we paint screens and provide rich user experience. Then there are business rules which I’ve seen loosely defined as how we manage the data and interactions with the services or repository of the system.
Because we tend to not treat these separately, we also tend to see them tied very closely together in designs and implementations. This presents multiple challenges such as making it harder to encapsulate logic and reuse it and the breadth of knowledge grows (i.e. you need to know UI programming and API/data model programming). MVC is one pattern that attempts to address these challenges, and there are many other patterns that address them as well. Get ready for the twist...
On projects with lots of UI rules that are tied closely with lots of business rules, these challenges are compounded. Especially when you consider how we can go about testing all that intertwined code.
There is lots of anecdotal evidence to support that testability remains one of the biggest challenges on projects with hundreds of interfaces. When looking at the cost/benefit of different designs for large applications we have repeatedly seen cost of testability to be one of the single biggest factors in terms of monetary impact. We can argue a design on technical merits all day long and have differing subjective opinions, but we are in the business of software so we have to be able to quantify the impact of a design in terms of cost also. My personal experience has found that the cost to test is one of the most easily overlooked. Having no one else on this thread bring up the subject as a crucial factor sort of reinforces my point.
Being able to write automated tests is imperative when we have hundreds of UIs. Separating the two types of code means it is significantly easier (read: less time, less custom skill, less money) to craft the thousands of test cases required and the controller logic can be run without additional user windows and workstations. This is because the test cases are standard API code, not rich UI code. In these cases the UI acts as the test without providing an actual UI, instead it just executes the controller to test the business rules.
It doesn’t just make the tests of business logic easier to write, maintain and reuse, it can actually increase code coverage allowing us to get to exception areas of the code that default UI logic would prohibit. For example the UI rules for the initial type of application being constructed don’t allow certain behaviors. However, the controller must be able handle them so that other types of UIs can also be crafted. If we only test against the UI directly (read: the actual UI we are delivering to the users in the first release), we won’t test those hard to reach places. If we don’t test those hard to reach places then when we finally do build the second or third kind of interface and it reaches there, we find new bugs in code we thought was tested well. Automating the controllers allows us to minimize this risk.
To sum up: yes the MVC-class of pattern allows us to encapsulate logic, and yes it can provide significant reuse of code, and very definitely yes it can be argued as good design. But in business terms, we often forget to make the leap to testability as a primary motivator when time to quality gets really small.
Too often we swap our opinions on technical subjects from our ivory towers without considering the business factors that should be influencing us.