Traditional software engineering literature states that a software development project starts with a customer need which is 'translated' into a set of requirements. These requirements then are given to a 'development team'. After a period of time, this team will deliver a software system that will make the customer happy. And everyone lives happily ever after.
What is wrong with the above scenario? It tends to simplify and gloss over some critical issues.
1. Users are not always clear about the problem. This would mean that the information they provide is incomplete or comes as a personal view point.
For example, If H. Ford asked the general population what they really needed most in 1890 - the answer would have been "a comfortable horse carriage". As an answer this is quite valid, however the real issue is the definition of "comfortable". It could mean "less smell", "better suspension", "softer seats", "air conditioning" and the list would go on. One aspect is certain -- most will not be thinking in terms of "an internal combustion engine", "car radio", "DVD player" etc.. The reason is mainly lack of proper awareness of the latest advances in engineering (or the fact that a better technology is not available), along with the natural tendency of the human mind to think within a constrained framework which is determined by the training/education/emotional state. The key point here is the fact that they asked for a "horse carriage" -- the elimination of the horse was never in their minds.
Good software is built by teams that take input from the clients and integrate that with the current advances in technology to produce a solution that is 'different' and may often break the innovation barrier.
2. Translating the users 'real needs' requires an in-depth understanding of the 'users mental model', the constraints that they face in doing their work, the 'real goal', the core aspects that cause them the most pain. Unfortunately, to do this effectively you need to have the vocabulary that the user has. The development team must use and think with the vocabulary/language of the user. Once we start looking at the language, this invariably leads us into its closely associated ally -- 'the culture'. Language and Culture are very closely related, almost to the point where in practical terms they are inseparable.
Good software can only be build by a team that speaks the customers language and lives (or appreciates) the cultural context that the user lives in.
3. Software systems once built live in a certain infrastructure, here they tend to grow and are adapted over time, i.e. they evolve in an environment. The more components that a software system has to interact with, the more risk we need to watch out for. The sooner the information about this infrastructure and interactions is known, the better it is for the project. For example, could you build a house within out knowing something about the location? Will it be in a rain forest? In a city? On a noisy street? All of these aspects have a bearing on structure of the problem as well as the solution. As such, they determine the overall constraints that one must be aware of to solve the problem.
In a mathematical sense .. we have a problem which is like this - "Given X = 3, What is X*2?". If we did not know the value of X?, we cannot solve the problem. When building a software system -- there are a number of variables that need to have values associated with them before we have a chance of solving the problem. If the value of these variables is NOT know -- early phases of the development effort would have to be in ensuring that we do have answers for it.
Good software can only be build by a team that is aware of all the constraints that have to worth within. The earlier this information is provided, the lower the risk. Early phases of the software development effort should focus on minimizing (eliminating) these risks.
4. An interactive system cannot be properly specified in a static document. We can create static models with the time component (e.g. a Dynamic UML model). Unfortunately, most users are not trained in reading UML, just like most people would not be able to properly read an architects blue prints for a house. Further, these models are very limited because they do not incorporate or capture the 'actual/real' feedback that takes place between users and the software. It is possible to explain a game like 'Quake' with models and words? Does it really communicate to the users? How do we communicate "coolness factor"?
If we cannot properly communicate the intention of the development team, how can the client provide feedback that is of value? The only viable and practical approach is via prototypes that communicate the key aspects and ensure that the very interactions can be communicated. The downside of the prototype is that it often tends to limit the clients mind to the way the problem has been solved -- rather than put forward various options available. Given sufficient budget, we can build multiple prototypes each highlighting different interaction models. The risk is reduced, but it still exists and it is important that we acknowledge it.
Good software can only be build by a team that communicates the interaction models via a usable prototype. They would also be aware of the inherent limitation that the prototype lives in a temporary space and is not a true reflection of the correct/final solution.
5. Software is built to reduce or eliminate pain points (of the various users). There is a certain goal state which will remove the pain. In semi mathematical terms - "Given constraints X, Y and Z. Search and find a path that will remove/reduce pain point P". The path is the final solution. Very closely associated with this aspect is the fact that most users spent a large part of their time retrieving information, i.e. they use computer systems to find information rather than put information into the system. 80% of the interactions with a system would be to get information out, rather than put information in.
Further, the best way to move forward is by ensuring we have a good understanding of the various types of information that the users would want out of the system. If this is available, the actual inputs for the most part can be derived by inference.
Good software can only be build by a team that understands the global pattern of data input and output in the system. Is the system being built to capture information? Does it provide a bunch of reports? But, the critical issue is of course -- can the team trace every input and output back to a pain point?