Don't Fail to See the Forest for the TreesLooking back on hard projects, I think more often than not, we discover that the reasons for the projects failures were obvious the entire time - but nobody recognized them.
A case in point: On one project I worked on, a fundamental failure to understand a specific part of the problem domain was detected very early. In the course of setting up a problem-domain object-model, the architecture team was able to agree quickly on an object-model, which covered almost the entire required functionality. Except for one spot of collaborating classes - we kept discussing this point literally for days, without converging on any meaningful solution. (Failure to converge is a warning sign in itself - it usually indicates the existence of some deeper problems.) Eventually we run out of steam and convinced ourselves that we had reached a common understanding. However, in the course of writing up the documents for the object-model, it turned out that the members of the design team had wildly different ideas as to what this common understanding was!
Easy to see, you might say. The failure to fully understand the problem domain was evident, and of course you can't build software for something you don't understand. Moreover, this failure was detected early on, in fact in the first two or three months of the project, during requirements analysis, exactly when it should have been adressed. Still, we never realized.
When the software was finally declared "complete" and handed over to the customer (ridiculously behind schedule and over budget, of course), the functionality related to this part of the object model was still not implemented, and there was no hope that it ever would be. The really shocking news, however, is that in the agonizing year-and-a-half that lay between, this same point never really left the public eye - leading to heated discussions among team members themselves, among developers and managers, among managers and customer representatives... Everybody felt bad about this particular feature, but nobody ever stood up and said: "We have a problem! (Now what do we do about it?)"
This is the point I am trying to make: Problems that, with hindsight, should have been obvious the entire time apparently were not that obvious - but the discomfort surrounding these issues was palpable nevertheless. Discomfort at any level should be a warning sign. However, given the nature of the human mind, there are at least two barriers to turning lingering discomfort into action: Wishful thinking and laziness. The first makes us pretend the discomfort isn't really there and makes us focus on all the things we feel good about. (And believe me, we really felt good after finishing that object model!) The second prevents us from taking decisive action ("Well, I don't really feel good about this particular part, but we all agreed upon it, didn't we?").
The task therefore must be to cut through these barriers, to realize the potential of gut-feeling, to detect problem spots early on and take decisive action to address them. I guess one way to do so is to address the discomfort issue directly. As part of any technical review, document sign-off, or design discussion, the question should be asked of every participant: "Which part of this do you feel least good about?". This question is more specific than the more common question: "Do you feel good about this?" and also counteracts the tendency to ignore the unpleasant by directing the attention directly on it. Being specific makes it easy to answer: after all, there is always something I like least about anything - even if I am fascinated by the object as such.
Requiring an answer to this question from every team member should
bring the tell-tale sign of hidden discomfort out into the open. It
won't solve the problem for you, but at least you knew you had one -
if you choose to listen! But this brings us back to the beginning of