Archive for October, 2009

Software Quality – Pragmatics

This article continues my series on Software Quality. My thesis is that we judge quality using the same inbuilt sense of aesthetics as we would a work of art or an everyday object, albeit at quite a high level of abstraction.

The design industry has a lot to say about this kind of thing and no one more so than Massimo Vignelli, who summarised his core ideas in The Vignelli Canon. I am following each part of the Canon, this part being Pragmatics.

Whatever we do, if not understood, fails to communicate and is wasted effort. – Vignelli

No matter how cleverly we design something, if it is not understood then that design has failed. Software is complex and some decisions will need explanation, but if the design is still not understood then the effort in producing it is wasted.

Complicated, confused designs are very common in our industry. They are often the result of confusion in the minds of their developers, analysts and users. A confused mind will produce a confused product. These projects usually limp along before collapsing, mercifully, under their own weight, but not after many years of very expensive and wasted effort.

We should be careful not to confuse a complex solution with an accidentally complicated one. Some systems are unavoidably complex and what we expect to find there, as in all systems, is a set of core principles that underpin the whole edifice. Without clear, strong and forceful decisions that provide structure to systems, there will be no clarity and plenty of confusion. This is not to say that those decisions are carved in stone. Constantly changing environments and requirements are a fact of life in software and so those decisions will need to be revisited and reworked. However, it is much easier to move from one set of clear and strong design decisions to another, than it is to rework a confused system.

Having clear, strong and forceful decisions is the only pragmatic choice we can make. Allowing ambiguity and confusion is not pragmatic, it is simply sloppy and is the easy way out in the short term.

Vignelli sums it beautifully:

• We like Design to be forceful
• We do not like limpy Design
• We like Design to be intellectually elegant – that means elegance of the mind, not one of manners, elegance that is the opposite of vulgarity
• We like Design to be beyond fashionable modes and temporary fads
• We like Design to be as timeless as possible
• We despise the culture of obsolescence
• We feel the moral imperative of designing things that will last for a long time

This is pragmatism in any field, and no more so than in software.

TDD from a Control Theory Point of View

Before becoming a developer, I was an academic at University College London. We built the world’s first homodyne and heterodyne phase locked loop with semiconductor lasers for oscillators instead of electronic oscillators. Sounds easy, right? But the problem is that because lasers oscillate at high frequencies (it’s light after all), a delay of a few hundred picoseconds around the feedback loop is significant and results in the system becoming unstable.

Indeed, any system with feedback can become unstable if the delay around the loop is significant. There are things that one can do to prevent instability but the best thing to do is remove the delay if possible.

In software, there are many feedback loops. When you write code, often the first feedback you get is whether it compiles or not. Can you imagine the pain if that wasn’t the case? Waiting a few weeks to find out whether the code actually compiled would be ridiculous. Right?

Fortunately, most software developers have a go at making sure their software actually compiles. Some don’t, but thats a different article.

Testing is another feedback mechanism. So how is it sane to wait months before finding out that your code actually works? It isn’t, thats crazy talk. TDD helps in a number of ways: it helps you to think about what your code will do before you think about how it will do it; it provides a safety-net for all those refactorings you will need to do; and it tells you that the code you thought you wrote is what you actually wrote.

The instant feedback obtained by TDD is a stabilising mechanism to ensure that what is written is correct and that you haven’t broken anything else inadvertently because all that other code in the system is also tested.

But what is meant by stability in this context?

The main instability is the code – wait – test – fix – repeat cycle. During the wait and test phases, new code is being built on top of the broken code, and the fixes themselves often introduce new defects. This results in increasingly painful fix phases. What is worse is that there may be many overlapping loops like this which is utterly chaotic!

This chaotic process results in developers working in a panicked, crisis mode which leaves no time for refactoring, reflection about improving the codebase, or writing tests. It’s very demoralising as the deterioration in the codebase cannot be stopped.

The end result is a brittle, sprawling mess of a system that is now not in any state to be tested or repaired without heroic effort from the developers, and buy in from business stakeholders. And we know how that story ends…

Site Designed By Top Left Design