A couple of months ago I had an interesting discussion about requirements with Johan Zandhuis, Fiona Charles and Mohinder Khosla on the EuroSTAR conference blog.
Johan said something that I wanted to mull over for a while before responding. As so often happens real life intervened and I got caught up in other things. Finally here is my response.
Perfect requirements don’t exist, you’ll need infinite time and money to reach that. And infinity is more a mathematical thing, I never have that in real life…
But the main point that I intended to put forward is that we should put more effort in understanding each other BEFORE we start coding.
Sure, we can’t have perfect requirements, but the problem is deeper than that.
The idea that you could derive perfect requirements with infinite time and money has interesting implications. It implies that greater resources can produce better requirements. I believe that is true to only a very limited extent; it’s certainly less true than software developers and testers have traditionally chosen to believe.
Yes, more money allows you to hire better people. But giving them more time is only effective if they’re working the right way. Usually we are not working the right way, and that applies especially to “understanding each other before we start”. If we are working the right way then we can forget about the idea that requirements could ever be perfect, and certainly not perfect and detailed.
There are three related questions that come to mind. Do we really understand requirements? Is it conceptually possible to define them precisely up front? Do we even understand what we are doing when we try to come up with a design to meet the requirements?
Do we really understand requirements?
Too often we make some huge, fundamental mistakes when we are defining requirements. We treat requirements as being a shopping list; the users ask for things, we build them. Also, we get requirements mixed up with design solutions; we decide that something is an essential requirement, when it is really only an essential feature of an optional design.
However, it’s not just that we get it wrong. It’s an illusion to think we could ever get it right, up front, even with unlimited resources.
Fred Brooks stated the problem succinctly back in 1986 in his classic essay
“No Silver Bullet”.
It is really impossible for a client, even working with a software engineer, to specify completely, precisely, and correctly the exact requirements of a modern software product before trying some versions of the product.
Do we really understand design?
It’s bad enough that we don’t really understand requirements, but to make matters worse we don’t understand design either. Software engineering has attempted to fashion itself on a rather naïve view of construction engineering, that it is possible to move rationally and meticulously in a linear fashion from a defined problem to an inevitable design solution. Given the problem and the techniques available there is a single, correct solution.
This is a fundamental error. To a large extent design is a question of setting the problem, i.e defining and understanding the problem, rather than simply solving the problem. Plunging into the design, or the detailed requirements, in the belief that our mission is already clear, stops us learning about the problem.
Design is an iterative process in which we experiment and learn, not just about possible solutions, but about the problem itself.
On the face of it that doesn’t fit comfortably with my earlier statement about the confusion of requirements and design. If the process of defining the problem and eliciting accurate requirements inevitably involves some form of prototype are the requirements and design not inextricably interwoven? Well, yes, but only in the sense that the detailed requirements are a mixture of possible design solutions and the implications of a higher level goal. They are not true requirements in their own right, abstracted from the possible implementation of a solution.
Users are typically lured into stating requirements in a form that assume a certain solution, when at that stage they have little understanding of what is possible and necessary. If the goal is abstracted to a higher level then the iterative process of exploring and refining the possible solutions can proceed more safely.
So messiness, uncertainty and experimentation are inevitable features of building software. That is the reality; denying it merely stokes up problems for the future, whether it is a failed project, or an unsatisfactory product.
Selective inattention and junk categories
This could have been a very much longer article, and I had to resist the temptation to plunge into greater detail on the nature of requirements and the way that we think when we design.
If you want to know more about our failure to understand requirements, and the way we confuse them with the design, then I strongly recommend Tom Gilb’s work. There is a vast amount of it available. Simply search for Tom Gilb and requirements.
If you want to delve further into the psychology and sociology of design then Donald Schön is a good starting point. His book “The Reflective Practitioner” helped me clarify my thinking on this subject. Schön’s examples do become lengthily repetitive, but the first 70 pages are an excellent overview of the topic.
If you’re interested in dipping into Schön’s work you could check out this article by Willemien Visser (PDF, opens in a new tab).
In his book Schön argues that the professions have adopted a paradigm of Technical Rationality, in which knowledge was learned and then applied, problems being neatly resolved by the application of existing technical expertise, i.e. by “knowledge in practice”. The following passage (page 69) leapt off the page.
Many practitioners, locked into a view of themselves as technical experts, find nothing in the world of practice to occasion reflection. They have become too skilful at techniques of selective inattention, junk categories, and situational control, techniques which they use to preserve the constancy of their knowledge-in-practice. For them, uncertainty is a threat, its admission is a sign of weakness.
Schön was not writing about software development, but that paragraph is a stinging indictment of the mindset that was once unchallenged in software engineering, and which is still far too prevalent.
Could we possibly get requirements as we traditionally understood them correct up front, even with unlimited resources? Is it a smart idea even to try?
Such ideas fall into the category of junk, that would require a huge amount of selective inattention if one persists in trying to believe them!