Introduction
Software projects and product all have requirements.
I'll come clean with you. I'm allergic to the word “requirements.” I generally get twitchy when I hear it. The term seems to have wide variety of definitions depending on contexts. The IEEE Standard Glossary of Software Engineering Terminology (1990) gives these three definitions:
- A condition or capability needed by a user to solve a problem or achieve an objective.
- A condition or capability that must be met or possessed by a system or system component to satisfy a contract, standard, specification, or other formally imposed document.
- A documented representation of a condition of capability as in 1 or 2.
While these three definitions discuss what a requirement is, they don't help us understand how we came to get it or how we determine if it's a good one, let alone great.
This isn't a book about how to write down requirements, although you'll learn some innovative ways to express requirements in a document or otherwise.
This isn't a book on how to manage requirements, although you'll learn some innovative ways to allow for and communicate change in requirements.
This is a book to make you look upstream from the requirements. To look at the approaches you take to understanding and deciding on what the requirements could be. And, of all the possible choices for what they could be, what specific choices are likely to result in great requirements.
In his 1987 essay “No Silver Bullet” Fred Brooks said:
“The hardest single part of building a software system is deciding precisely what to build.”
If you buy what Fred Brooks said above, and are troubled by it, this book will make that hardest single part of building software much easier. Requirements are Proposed Solutions to Problems
“42.”
“Forty-two!” yelled Loonquawl. “Is that all you’ve got to show for seven and a half million years’ work?”
“I checked it very thoroughly,” said the computer, “and that quite definitely is the answer. I think the problem, to be quite honest with you, is that you’ve never actually known what the question is.”
Many of you will likely recognize 42 as the answer to the “ultimate question” from Douglas Adams’ Hitchhikers Guide to the Galaxy. It's nonsense solution to "life the universe and everything." Turn to the person sitting closest to you right now and say “42.” If you’re not sitting close to someone, play along and imagine that you are. Chances are you’ll get a smirk, or a little laugh – because the person sitting next to you recognizes 42 as the answer to a question that no one knows. Which is a funny notion.
Now here’s a story that might be less funny.
If you’re working in software development chances are you’ve got requirements documents floating about. Pick up one of those now. Look for a particularly odd requirement. This shouldn’t take long to find. Turn to the person sitting closest to you and say that requirement out loud. Notice how similar the look you get back is to the one you got when you said 42.
If we understand a software requirement to be a solution to a problem that a user or business wants to solve, then we can start to understand how to determine if the requirement is great, merely good, or completely inappropriate. If we don't know what the business problems to be solved are, or who will use the software and why, then it's quite impossible to determine if the solutions in our requirements documents are great or inappropriate.
To understand the quality of a solution, we must understand the problems it's intended to solve.
Sorry to put that in print. It is indeed a bit obvious. But, if you buy the idea that requirements are solutions, look through the requirements documents your company uses and locate the problems those requirements describe the solution for. Or, talk to a few people on your development team. Assess their understanding of the problems the software is supposed to be solving for the business paying for it, and the users who will use it.
Be alert for people guessing. By that I mean looking at the requirement and inferring what problems that requirement addresses. A good solution often suggests the problem it solves. Quick inspection of a knife, or requirements for one, allows me to make all sorts of inferences about who its users are and what they're using it for. But ask my why the handle is wood vs. metal or plastic, and I'll have to start guessing. The reasons for choosing wood or plastic on the handle are far enough from my understanding of the problem that I'll need to.
"42" is an example of a solution to a problem, or answer to a question anyway, that's so distant from the question that I can't infer the answer. Given a requirement like this, any guess is as good as any other. "How many roads must a man walk down?" was the best guess at the "question" from Hitchhiker's Guide. What's your best guess at questions answered or problems solved by the requirements you're building today?
Now, let’s go back to the person smirking at you after reading an odd sounding requirement. Again, play along and imagine that smirk if you don’t have a person sitting next to you. The reason the requirement sounds odd is because it’s like an answer to a question neither of you know. It’s a “42.”
A lot of software is built by well meaning people who don’t understand the problems their requirements are the solutions for. That’s not so bad. What’s worse is that a lot of requirements are written by well meaning people who don’t understand the problems they’re describing the solution for. In software development, it’s not uncommon to see a requirements document describing a very sophisticated solution to a very poorly understood problem.
One can imagine the difficulty in assessing the quality of these particular requirements. We're left with evaluating grammar and clarity of communication. Unfortunately the eventual users of the software don't much care about the grammar and clarity of our requirements documents.
There’s a lot of discussion about failed software projects. I’ll make a bold assertion here:
Most software projects don’t in fact fail because they’re over time and over budget, but because they implement poor solutions to poorly understood problems.
Spark Gap or Chasm
OK, I think we can all buy that requirements are proposed solutions to problems. And, I think we can infer that the better we understand the problem, the better our likely solution will be.
The fine people at Cooper Interactive refer to the distance between what we know about our problem and a prospective solution as a spark gap - like the one in an automotive spark plug crossed by a small spark of electricity. It's a good metaphor. Oftentimes the solution to a problem isn't obvious and it does take a spark of innovation and invention to make the leap. In this book, I'll refer to that leap across the problem and solution spark gap as design. I like that word. It carries with it an appropriate implication of creativity. It carries with it in implication of responsibility on the part of the person making this leap - an implication I don't hear in the phrase "requirements capture and analysis."
This book will emphasize techniques and thought processes to close the spark gap - to make the little jumps of innovation and invention easier and more frequent. What I observe on many software projects is more of a vast chasm than a gap. The problems loom large and are often poorly understood. It's often difficult to understand if the software described in our requirements actually address the problems, let alone addresses them well.
Building a Gap-Crossing Design Methodology
If we'd like to predictably arrive at great requirements, meaning requirements that solve problems well and can be easily understood as successfully doing so, we'll need an approach that can help.
Let’s make a simple example out of something not related to software. Let’s talk about something as common as a toothbrush.
A toothbrush is a tangible product used to support the daily task of brushing teeth. It works in conjunction with other handy inventions like toothpaste, a sink, and running water. Most of us perform this daily task of brushing our teeth to support a couple of goals: not offending our neighbors with bad breath, and keeping our teeth healthy into our old age.
You’ll see a simple progression here from goals, to tasks, to the tools and steps necessary to perform the task.
/* need illustration: goal -> task -> tools + steps */
Now we take the toothbrush for granted. But before it was invented in 1498, it was much more common to use a stick or a piece of cloth to rub our teeth clean. You can see how improvements in technology and design have changed the quality of our collective teeth cleaning experience. And, we’re not done yet. There are electric toothbrushes that will brush for us, waterpiks that will blast our teeth clean with jets of water, and sonic toothbrushes that use sound waves to get rid of even more nasty stuff on our teeth and gums. All these teeth cleaning solutions are products of current technology and some inventive design. I’m still holding out hope that someone will invent something that makes it so I don’t have to brush at all – so that I can keep my breath fresh, and my teeth into my old age without doing a thing.
So let’s revisit our simple three step requirements building model:
goals -> tasks -> tools
Goals & Problems
Goals seem to be the most lasting bit of information we can acquire. For brushing teeth, those goals haven’t changed much for thousands of years. Sometimes we can express a goal negatively as a problem to solve: “your breath stinks,” or “this painful rotten tooth is killing me.”
Tasks
Given a goal or a problem, and a bit of desire to address it, we’ll likely try to figure out something to do about it. The activity of doing something in pursuit of a goal we’ll call a “task.” But, don’t overlook the activity of deciding which tasks are the best ones to do.
Notice that how we express our goals can result in very different tasks. Using a goal like keeping our teeth clean and healthy might motivate a task like cleaning our teeth daily. Using a problem like “your breath stinks” might motivate a task like putting something that smells overpoweringly nice into our mouth to mask the problem. Breathe mint and gum manufacturers make millions solving that one. So identifying, and phrasing, the problem motivates the tasks we’re most likely to engage in to address the goal or problem.
Tools
Given a particular task, the things necessary to complete that task are our tools. Animals that don’t build tools rely on their brains, teeth, and claws to perform their tasks. Humans are compulsive tool builders – software developers even more so. Given a task to perform, we’ll identify tools in our environment to help us perform that task. If a tool doesn’t exist, we’ll invent one. We’re also adept at repurposing existing tools for other tasks. Toothbrushes are great for cleaning the grout between the tiles in your bathroom. If you’re in software development, you might have noticed the clever ways users of your software adapt the tools you’ve built for them to tasks you’d never imagined.
To invent a tool, we’ll need to understand the task, and invent a tool that allows us to effectively perform the task. A good tool is easy to use and often employs very few steps to complete the task using the tool. Some tools support a number of different tasks. As a tool designer, we’ll need to think about and describe the tool and the steps for using it. If someone else is to build the tool we’ve designed, we’ll need to convey that description to the person that will build it. These are our requirements.
This is a simple one-two-three process. But, you might see how many things can vary or go wrong in it. How we identify a goal or problem can change the most likely tasks we choose to solve it. The tools we choose to design to support the tasks can be obvious and easy, or unobvious and difficult to use.
Software as a tool is more complex than a toothbrush. Software is often built to satisfy the goals of a wide variety of users and stakeholders that my never actually use the software. Often the tasks the software supports need to be invented along with the software tool that supports them. Often we need to invent and recommend tasks that performed using tools other than the specific software we're creating. There may be lots of problems to identify and lots of solutions to consider and test.
A Process for Designing Great Requirements
This book will put a bit of meat behind the process of arriving at requirements. I'll refer to the process that helps us arrive at requirements as design. I'll describe a variety of tools and techniques that make that help simplify the design process, help make it more approachable and repeatable, help narrow the spark gap.
I'll make recommendations that apply particularly, but not exclusively, to an Agile Software Development environment. The iterative and incremental nature of Agile approaches along with their emphasis on collaboration and testing provide particularly fertile ground for installing a culture of design.
This book will explain Agile Software Development generally. You or your organization need not practice a specific Agile approach to leverage these approaches to designing great requirements. You'll find that as you collaborate with others, if you emphasize the understanding of problems before proposing solutions, and emphasize continuous testing and validation of your solutions, you'll be naturally moving toward an Agile frame of mind. Please note that collaboration, problem understanding, and testing aren't the exclusive domain of Agile Software Development. Agile just provides an easy way to refer to approaches that have these characteristics.
Have Fun.