Using Test Driven Development certainly helps. You write a single component at a time and then enumerate all of the potential cases for inputs (via tests) before writing the code. This ensures that you've covered all bases and haven't written any cool code that no-one will use but might break.
Although I don't do anything formal I generally spend some time looking at each class and ensuring that:
- if they are in a valid state that they stay in a valid state
- there is no way to construct them in an invalid state
- Under exceptional circumstances they will fail as gracefully as possible (frequently this is a cleanup and throw)