I once wrote an article titled “A Time-Saving Programming Tactic That Doesn’t Work.” In this article, I lamented the tendency of many programmers to deal with software deadlines by simply coding away, without stopping to think about a proper software design. “I don’t have time to design the software!” they say, so they just start churning out code. The intent is to save time, but this approach almost never works except on the simplest of projects. Without a carefully considered design, more problems are bound to emerge, thus causing more time to be lost. What’s worse, many of these problems won’t become clear until the testing phase comes around, and by then, it may be too late.
Most of the feedback that I received was positive; after all, experienced programmers have generally encountered this pitfall time and again. However, one reviewer said, “This fella obviously knows nothing about agile progamming. With agile methods, you don’t need any elaborate designs. You can just start coding away, and you can save yourself a lot of time that way.”
I always appreciate honest feedback; however, I think this comment betrays a common misconception about agile software development techniques. It is true that non-agile methods tend to emphasize extensive up-front documentation and design; however, this does not mean that agile programming is synonymous with a lack of design or documentation. Rather, when agile methodologies are used, the designs (and documentation, as applicable) are iteratively refined as the code is tested and one gains greater understanding of the project’s scope and problems.
In other words, it would be grossly unfair to say that agile methods do not require any prior design. Agile methods are adaptive, not unplanned or undisciplined. I am by no means an evangelist for these techniques, but I do recognize that they go far beyond merely jumping in and coding away.
Personally, I tend to favor up-front design. I feel that agile techniques tend to be overhyped and overrated. I also believe that thoughtfully considered up-front designs will tend to save time and prevent a great many problems from creeping into the code. However, this does not mean that I would insist on a comprehensive up-front design, since in most situations, this tends to be unproductive. I find that it’s better to adopt a measure of agility. That is, I prefer to develop a reasonably thorough systems-level architecture – something more than just skeletal – and then refine it as bugs are found and ideas come along.
The reality is that most up-front designers will tend to do the same thing. They will tend to create an initial design, but they seldom have the patience to plan everything down to the fine details. Nor is this generally advisable; after all, agility advocates are correct when they say that one’s understanding of the required software functionality will tend to increase as the software is developed.
Similarly, skilled agile programmers generally will not abandon up-front design altogether. They understand the need to think things through and consider various approaches. They might write tentative pieces of code in an exploratory way, but that’s vastly different from simply jumping in and coding away. Even within an agile development process, skilled programmers will generally alternative between frenetic coding and careful contemplation.
Programmers need to divest themselves of the notion that one can avoid software planning and design on account of being “agile.” Agility means adaptability. It is not a synonym for coding by the seat of one’s pants.