[Previous entry: "C# for Java Programmers: Static Constructors"] [Next entry: "Software Process Improvement"]
07/11/2004: "Building Bugs in Double-Quick Time, part 1"
In a recent Yahoo! group posting, I came across an article entitled Building Bugs in Double-Quick Time. In summary, the article presents a view of the current state of the software development industry, asking the (by now) old question, "We don't tolerate this level of incompetence in other industries, so why do we tolerate it in software?" I would like to take some time to address the varying points in this article over several upcoming weblog entries.
Rather than argue against any of the author's points, I prefer to accept them all as hypotheses, then build upon them. I would rather simply describe how my approach to software matches up with the author's concerns, rather than argue the validity of those concerns. Now then, off we go.
Most development projects focus on the visible side (functionality and user interface), and ignore errors. Let us take this as a hypothesis, assume it to be true, then go on from there. I am going to take a chance and interpret this to mean that these projects put more attention on happy paths and the user interface and less on error handling and recovery. Is this necessarily a problem? It appears to depend on the code-level design of the system. I have worked on many systems where error handling and recovery were quite sophisticated: a deep, rich exception hierarchy, with excellent support for multi-language error messages, logging errors to databases, and even symptom databases that look at error message patterns and suggest possible problems. Why so much support for disastrous situations? Could it be that disastrous situations simply occur too often in the system? What if we could build the system to reduce the number of disastrous situations?
Having worked on these systems, and not merely observed them, I can state one unusual source of these disastrous situations: a lack of communication during feature development. To illustrate the point, I will recount a story (from a real project) of Team A, that delivered business logic commands to Team B, who built the user interface that exposes the commands. It is Team A's job to provide the "back end" and Team B's job to provide the "front end" of the same feature. When Team A delivers the commands, one of the Team B programmers looks at one such command and discovers that there are seven different ways of arranging about a dozen input parameters, each combination of which triggers different features (and not merely different paths through a single feature). The "B" programmer has to spend hours deciphering this command's programming interface before he can even try to use it. Eventually, the "B" programmer manages to jam the command into his user interface, spending well over a dozen hours figuring out how to do so, and while the resulting end-user experience is adequate, the "B" programmer dreads every defect report coming from the testing organization, because if it concerns this monster command, "B" will have to spend considerable time isolating the problem before getting his "A" counterpart involved in fixing the defect.
So what went wrong here?
I believe one serious underlying problem here is that two separate teams are working on the same feature. If the two programmers involved in this story were on the same team, working together closely, then they would have been able to agree on a sensible programming interface for the command. For example, they could have designed both the user interface and the business logic programming interface together, with feedback in each direction, greatly reducing the chance that "A"'s design would leave "B" scrambling (or plodding) to figure out use it. They could have built up the design path by path, starting with the happy path and ending with reasonable error scenarios, and after each path they would have working code that demonstrated the feature they were building. They could have begun delivering the feature to the testing department earlier, and could even have included the feature in a customer-visible beta release, obtaining valuable feedback from the people who plan to purchase the software and use the feature. If I could wave a magic wand and change one thing about this story, I would put the two programmers in adjoining offices and ask them to deliver working code, even though the feature would not be completed, by the end of the week. Placing focus on even completing just the happy path, and here "completing" means running, tested and documented, they would get valuable feedback to help them drive the design of the remaining not-so-happy paths. Putting them together and encouraging them to work closely together would increase the likelihood that "A" would deliver what "B" needs the first time.
