Yogi Berra said: “You’ve got to be careful if you don’t know where you’re
going ’cause you might not get there!”
Stephen Covey said: “Seek first to understand.”
Both statements are applicable to software development as well as many other areas!
Both statements should be kept in mind as you write your requirements to help you make sure your requirements will assist you in delivering a software solution that meets your users’ needs. You can find all sorts of templates and formal processes for requirements of various kinds, and while they are useful, the biggest problem I’ve found is that most people confuse defining the need with proposing a solution. As soon as a requirements document contains any part of “how we’re solving this”, you’ve crossed the line into presupposing that you already know what the problem is and can stop listening.
We’re all problem solvers. Presumably, this is part of why we’re in this business. But if you are proposing solutions before you’ve agreed on the definition of the problem, you’re jumping ahead to the “fun” part prior to doing the legwork. And you’ll end up later paying for that mental leap as the details of the problem become known, or you find that some assumption you are not aware of making conflicts with your users’ needs. More often than not, you end up solving the wrong problem (which your users may not even care about) and you’ve doubly frustrated the user by a) mucking around with something that didn’t need fixing and b) leaving them still frustrated about the original problem!
So how does your process work? Be honest! Does your design start before the coding does? Do you throw things together for a demo at a tradeshow and then think you’ve got a jump on that functionality? While the ideas of iterative development and prototyping sound great in theory, how much code is actually thrown away later in real life? Unfortunately, very little. Once it exists, and has been paid for, it is very difficult to start over.
A typical scenario might be:
- Someone gets an idea for a product or a budget for solving a perceived problem.
- Before the idea is fully defined someone gets a programmer to “quickly throw something together.”
- As the requirements are defined, hopefully in writing but often only in response to looking at the prototype, the program that was thrown together gets modified, over and over again. Show the prototype to different sets of people and you’ll get drastically different feedback, further confusing the issues. As more details are discovered in this phase, the first description of a project might not be recognizable in the end as the catalyst for what is built. Too many things are discovered that cause changes to basic assumptions about the project.
- Once it’s all “clear” and “well-defined”, when it comes time to finalize things, the programmer is thinking “Great! Now I get to build it for real.” Meanwhile, management is saying “Wait! It’s already built. Can’t we just add on a bit and use what we’ve got?”
The danger with this method is that management sees a working prototype as a beginning point. Programmers see it as a hack they did to demonstrate viability (although some see the same thing as management-but not usually those that have done much maintenance or had to take over someone else’s hack!). They are stuck with taking the scaffolding of a prototype and building around it, leading to a difficult to maintain product, which will get added onto again for the next release and become even worse. Users will wonder why the heck they just can’t figure out what they want to do and do it! And believe me, if you can’t afford to build it from scratch for version 1.0, by the time you’ve added on features for newer versions, the idea of starting fresh becomes more and more expensive-if you’re lucky enough to still be in business for future versions.
My rules for requirements are fairly simple and easy to keep in mind no matter which formal methodology you are utilizing:
- Make sure your problem description does not include any part of a solution or you are blinding yourselves to alternatives and/or assuming you know more than you probably do.
- Define your requirements with user/business oriented tasks and needs. For example, the user never needs a database: that’s a solution. The user needs a means to collect, organize, associate, and categorize certain types of information and while you can define the types of relationships and constraints necessary from a business perspective, keep in mind that users are not database designers. Define their needs and propose the data relationships in a different document.
- Make sure your requirements include things that are necessary. Don’t add things because they’re “easy” or “cheap”. There have been many, many unsuccessful products that had a laundry list of features implemented that never satisfied their market.