The most important factor that contributes to a successful software project is ensuring that the development staff has a good understanding of the requirements. Incorrect requirements almost guarantee incorrect software behavior. Most often, however, the requirements aren't clearly incorrect, but rather they are vague, ambiguous, or make incorrect assumptions about the best way to apply technology to solve the problem.
The original title of this post was "Writing Good Software Requirements", but I realized after writing the previous paragraph (irony noted) that writing good requirements is actually part of the problem. Having written software my entire adult life and much of my childhood, I've been most effective writing software for myself. This software has always done exactly what it was supposed to do (technical bugs notwithstanding) and the reason is because I had a visceral and complete understanding of the problem I was trying to solve and what factors would directly influence my impression of success.
It follows then, that the number one goal is to effectively communicate the problem that the software is meant to solve. By far, the most effective way to do this is to make the developer have the problem you want solved. Need a better solution for authoring blog posts offline? tell a developer that this is the only way they can do it and I guarantee you'll get a decent solution. Yes, it will likely need some visual tweaks and you'll need to make some changes to accomodate users that are NOT developers, but the essence of the problem will be solved very quickly.
This is obviously not a way to do things in the real world, but thinking about the problem leads us to some basic rules to follow when gathering and communicating requirements:
Step 1 - State the problem clearly
A common misstep, especially when the person assembling the requirements is technical, is to skip outlining exactly what the problem actually is. Folks will jump immediately to a solution and assume everybody understands why we need it. For example, let's supposed we are create a system to enable users to write blog posts. For the author, one problem with online editors (like blogspot) is that it's not possible to author posts offline. One version of the requirement is to say something like "enable users to run a copy of the blogging platform on their local machine".
There are probably a thousand business analysts who looked at that statement curiously and thought "that's PERFECT, what could possibly be wrong with that as a requirement?". Well, there are a number of problems, but first and foremost, it makes a rather large assumption about the mechanism that should be used to do the offline editing. This leads to a situation where it limits the developer's ability to use the technological assets at their disposal to solve the problem.
The better way to communicate the requirement is to start with a statement of the problem. "Users cannot author blog posts when their computer is not connected to the internet". This initial statement gets the developer thinking about the REAL problem, and not imagining other possible reasons that someone might want to run a copy of the blogging platform locally. More importantly, it also enables the developer to start creatively thinking about the problem in terms of the end user instead of as merely a technical problem to be implemented. This has the added benefit of forcing (one would hope) the developer to start taking ownership of both the problem and it's solution and helps avoid a situation where one implements a really crappy solution to the problem "because that's what they asked for".
Step 2 - Clearly express non functional requirements
Once the problem has been clearly articulated, the next step is to clearly communicate what other factors will influence the success of a solution. These factors might be "Users should be able to author offline posts in their iPhone" and "users shouldn't need to download any additional software to use the solution". These requirements are what architects would refer to as "non-functional requirements" or NFRs. The problem with these statements is that , again, the developer is left to their own devices as to WHY these requirements even exist, which leads us to:
Step 3 - Clearly express the reason for the non functional requirements
A super way to communicate these is to explain (from a business or user perspective) WHY it is important for these requirements to be met. The iPhone requirement might state something like "20% of our customers have iPhones and we believe we can capture this market and increase our market share by this amount if we have this capability". For the second NFR, it could be something like "90% of our users are non-technical and we believe they would not be willing to install additional software for this capability"
If you are a person responsible for communicating requirements to developers, starting with these three steps will guarantee that you're starting on a solid base and will enable you to supercharge your development team. Realistically, using these simple steps as the cornerstones of your requirements gathering process will yield immediate positive results. If your developers are complaining about "bad requirements" or you feel that the software your development staff is unable to produce the desired results, take a look at what you're communicating to them and make sure these things are being accomplished.
In a subsequent post, I'll outline some more specific pitfalls when expressing requirements (especially in written form) and give some helpful tips on how to avoid them.