How to cope with bad code [closed]

One of the most unpleasant (and unfortuantely most frequent) situations I am confronted with in my all day life as a developer is that I have to fix bugs or add features into code that is badly designed. Now as a good craftsman I would like to leave the code in a better state than I found it. Often new features can not be implemented if I do not refactor the design. Well - they could, but that would make the code even worse.

Unfortunately this is exactly what I tend to have a hard time with. I feel that if there is one thing that is hard, it is to refactor bad code, especially when you have deadlines. Touching bad and complex code that more or less works is scary. As a result I introduce even more clutter when I hack a new feature into the code without modifiying existing code.

Now my question is How can I learn to cope with bad code? How can I learn to understand huge codebases and then refactor parts of it without breaking stuff that already worked and without exceeding the deadline? Is there any literature you can recommend? Do you have any general tips for me?


General tip:

if (it is working)
   Do (not touch it);
else
{
   Make (as few modifications as possible)
   Or (it will stop working at all);
}

This is experience of generations.


Michael Feathers wrote a good book about this subject exactly.

Working Effectively with Legacy Code.

Another great book is by Martin Fowler, Kent Beck and others:

Refactoring: Improving the Design of Existing Code.


Refactoring needs the safety harness of a unit test suite to remove that "Have I broken it?" feeling. Covering the bad code in a blanket of tests will help you whilst you strive for good clean code.

Pex is a tool that I find useful (if you are in the .NET world) for creating tests for legacy code.

Legacy code == code without tests!

Kindness,

Dan


When I have to deal with adding functionality to bad code, my usual approach is:

  • Write automated tests for every important feature that must work (as most bad code doesn't have any tests).
  • Do code changes.
  • Make sure the tests are still working.

That give you at least some confidence that you didn't break everything. As for how to learn coping with bad code, I guess it's just about experience.


Well, if you're going to refactor large amounts of code in a project I'd recommend using some decent version control, so you can branch and fall back easily. Given, this is probably is an open door, but crucial imo.

Furthermore, before you start getting in to complex OO, try breaking methods and functions into smaller ones. Ensuring some level of atomicity in each of the functions, which makes the code alot easier to maintain, read and manage. It's all about the small stuff, break it down into logical units of operation, I'm doing a refactor action on a 1k lines method. It does al sorts of fancy stuff. My first goal is to get as much stuff out of it in smaller pieces, when that's done I'll start thinking about a better OO design, which is much easier because I've a much better grasp on things.

Aspirin works good too.