“Kind of software being developed” and “Personnel factors” are often out of the control of the developers and you have to work with what you have leaving only “Project size”.
The three pillars you have mentioned are tools. Sort of like carpenters arguing which hammer is the best, there may be slight differences between them but there are larger gains to be found elsewhere.
I can’t think of any instance of a past project that I have been involded in failing because we didn’t use one of the tools mentioned.
What has worked for us:
- Client Buy-in
- Programming Development Standards
- Iterative Development
Client Buy-in:
Have the Use Cases been developed with the client?
Are actual end users of the software working with the Devs and not some management type?
Has the client prioritized them?
Has the client walked through them?
Has the client signed them off?
Has the client worked with Demos/Prototypes?
Is the client using vague/abstract terms or defining the project more in terms of what they don’t want instead of what they want?
Programming Development Standards
Have you created a glossary of terms? Does the word “Customer” mean the same thing to everyone on the team for example?
Is there a common naming strategy/convention used for the whole team?
Are there templates illustrating common operations such as function definitions/database access/error handling
Do the devs have access to common source code and utility functions used by each of the devs? Are they stored in a common area so your devs aren’t re-inventing the wheel (repeatedly)?
Do you have a standardized testing standard/strategy?
Iterative Development
Are you delivering iterations of the software regularly?
Walking through them with the client?
Here is where you manage the project size by developing the parts of the application needed the most first, and add functionality with each iteration.
If the client isn’t properly involved, the project is dead. If the customer isn’t reviewing the use cases and baselines the project is dead.
If the team isn’t speaking a common vocabulary the project is going to have a hard time integrating its work and probably end up dead. If there are no templates/standards developers can’t be easily moved in and out and the project will have a hard hard time being completed.
Test cases allow you to test the interfaces of the designed classes before actually coding them. If you can’t write a test case it’s a pretty good sign it’s a bad object. The ability to unit test all of the classes makes the software more resilient and easier to make large changes to the code base (I don’t consider unit testing a tool here, you can test in many ways, just having a tester follow numbered steps on paper for example)
Monolithic development allows the team to spend years not delivering anything and the project will end up dieing. Iterations force the developers to deliver regularly and allow you to gauge forward progress.
Over reliance on tools would be part of the recipe for failure from my past experience. They can help to create a Single Point Of Failure in the system and things can grind to a halt if something goes wrong. They may be overly complex and result in the devs working around them or just ignoring them.
Sorry for being so long …