While the best advice is, as every other poster on this topic has noted, to write tests, I've often been in the situation where this is unrealistic. If the code is that bad(1000 line methods, embedded and undocumented magic numbers, code duplication, etc.etc) it's also likely to have another problem, which is that it's deeply coupled and components are almost impossible to isolate .
(examples
- a codebase that loads up, and caches, hundreds of different database objects on startup. Components assume random parts of the cache exist, and parts of the cache assume other parts of the cache - inotherwords, you have to load the whole thing to get anything
- code dependant on static, and promiscuously public, state variables, where it's impossible to determine who's setting those variables, or even what they mean)
Best suggestions I can come up with:
- Try to fix the easy/obvious things first. Hardcoded paths, magic number references, obvious code duplication. Perhaps a quick release that gets rid of the worst 20% of the violations will be of low risk and make the next steps easier to accomplish.
- Get organizational support for refarctoring - there's often no will or desire to do work that doesn't add immediate functionality, and risks breaking existing code. There are, of course, great arguments for refactoring, but not everybody buys them. If the organization doesn't support it you may have to give it up.
- Bring other developers around to the same view - if they're any good,they're probably as unhappy with the codebase as you are. If new code is built to better standards and people are motivated, they'll start to fix older code as tweaks need to be applied.
- If a particular subsystem is really, really bad and has reached the point where new development is nearly impossible you can probably use this opportunity to rebuild it.