12/01/2007

Personas of a Failing Software Architecture

Personas always interested me. IVR systems have them, Usability folks leverage them, heck even Microsoft had Mort, Elvis and Einstein. I like to think that a good architectural pattern can also be a persona of sorts and the anti-patterns covered by Joseph Yoder in his Big Ball of Mud paper certainly hit home for me.

Today, a business drives the need for software architectures that can confront rapid change. It has become increasingly clear that software architecture methods have evolved in ways that are distinct from the more formal waterfall methods. The pace of evolution in development of systems used to be measured in years, now it is increasingly measured in months. The untapped power of software's ability to meet change head-on is one of its most striking factors, yet it is often overlooked because of the very same business trying to leverage it. It is therefore, an issue that every software designer must address.

Because organizations have different needs, and requirements change over time, it is my opinion that the need to adopt an iterative architecture to build systems that can adapt to change as requirements change is an integral part of software architecture. Iterative architecture methodologies manage change through a series of transitional architectures which aim to deliver a final target architecture in the future. It is much easier to make a course correction having only gone part of the way. 

At any rate, try to laugh a little as you read through these, we have all been there in one way or another!

Shantytown
You need to deliver quality software on time, and within budget; So, you focus first on features and functionality, then on architecture...
Shantytowns fulfill an immediate need for housing by bringing available resources to bear on the problem. Loftier architectural goals are a luxury that has to wait.

Maintaining a shantytown is labor-intensive and devours a lot of development time. Developers are often wasting a good portion of their time to improvising repairs with the materials on-hand: From roof repair to ad-hoc sanitation, its a downward spiral to an unmaintainable system. All too many of our software systems seem to be, architecturally, little more than shantytowns. Administrative tools and infrastructure support are usually inadequate, primitive and infrastructure such as libraries and frameworks, are under utilized or even non-existent. In the wake of this "progress" developers continue to plow ahead, unchecked, to grow other portions of the system without governance. Deadlines hang like vultures and architecture takes a back seat to a hurried fix.

Permanent Prototype
You need an immediate fix for a small problem, or a quick prototype/proof of concept.

Like a temporary storage shed you have every intention of quickly tearing down to replace with something more permanent, prototype code often has a way of enduring indefinitely. The temptation to continue to use the temporary one for "a while" can be difficult to resist.

Often, when you are prototyping a system, you are not usually concerned with how elegant or efficient your code is. You know that you will only use it to prove a concept. Once the prototype is done, the code will be thrown away and written properly. As the time nears to demonstrate the prototype, the temptation to load it with impressive but utterly inefficient realizations of the system’s expected functionality can be hard to resist. Sometimes, this strategy can be a bit too successful. The client, rather than funding the next phase of the project, may slate the prototype itself for release. Do this often enough and you'll have a nice little shantytown over time too.

Sweeping it Under the Rug
Spaghetti code is hard to understand, repair, or extend. If you can’t easily make a mess go away, at least put a pretty face on it. This will help to restrict the disorder, keeps it out of sight, and can open the door to additional refactoring.

If you can’t make a mess go away, at least you can hide it. Urban renewal often begins by painting murals over graffiti so why not do the same to your code? There are valid reasons, other than aesthetics and guilt for trying to clean up messy code. With a looming deadline you've got some code that works, but could stand a bit of architectural integrity. You know there are good ideas buried in there somewhere, but that if you don’t start to make them more evident, they may be lost forever. Eventually, you sweep enough things under the rug and it becomes a monster you no longer wish to see. At first glance, it can sometimes terrify those who would dare try and control it but the first step on the road to architectural integrity is to identify the disparate sections of the system, and consolidate them into logical portions of a bigger system.


Total Rewrite
Your code has declined to the point where there is no point in going on. Repair, or even comprehension is not even a thought; So, toss it and start over.

Sometimes it’s just easier to throw a system away, and start over. Examples abound, but starting over can often be seen as a defeat. I've seen people pulling covert ops the US government would be proud of, to hide project re-do's. One good reason for starting over might be that you feel that you've got the experience you need to do the job properly. One way to have gained this experience is to have participated at some level in the "unsuccessful" development of a previous version of the system. Bear in mind, however, the new system is not designed blindly. It is essential that a thorough post-mortem review be done of the old system, to see what it did well, and why it failed. Bad code can bog down a good design but a good design can isolate and contain bad code. Remember...Refactor!

No comments: