Thursday, July 30, 2009

TODO or not TODO

In the spirit of continuous improvement and XP's recommendation to always keep the code pristine clean (Refactor Mercilessly), I often perform a lot of refactorings to simplify the code as much as possible as the accumulated debts over the many months of a project can otherwise make working with the code intolerable a few years down the road.

The way I look at refactoring is it's like maintaining your car or cleaning your room. Do it continuously and you'll enjoy driving around or relaxing in your room. Ignore it, and a year later your car is not working as it should anymore and your room is completely intolerable except for running in to sleep and then run out again.

Unfortunately though, while I get insights for many refactorings that can make a significant dent on code simplicity, I often don't seem to find time to perform all of them when approaching a deadline. Should I ignore them and hope for the best? What if I ignore them, and after the deadline, I don't remember them anymore?

The best solution I personally found is to add a TODO in the place where the pending refactoring is useful.

But some developers from the agile community would immediately flinch and say: If you put off refactorings by adding TODO statements, you'll never get to do them and your code will be littered with them.

I used to have that fear myself till I gave that approach a try a few years ago.

Turned out that since continuous merciless refactoring is in my blood, I never find myself ignoring refactorings and letting the code rot. Quite the opposite, I sometimes almost miss deadlines to ensure that the code is in pristine condition.

Nonetheless, given that I have to let go of some refactorings to meet deadlines, I often forget them afterwards. One approach I tried to remedy that is to add reminder tasks about the refactorings in my task management app. Unfortunately, these often get ignored when the list grows too big.

So, I finally resorted to adding TODOs within the code, and I found a number of benefits as a result:
  • Refactoring ideas are preserved next to the code that needs them, thus maintaining context
  • Other developers see them and get an opportunity to perform the refactorings in the process of fixing a bug or adding a new feature
  • Developers are constantly reminded about them whenever they see the code that can benefit from refactoring
Therefore, TODOs are not used as a crutch to avoid performing refactorings when working in the code, they are used instead as reminders for refactorings that there was absolutely no time to perform before some deadline. They are placed right next to the code that needs them, thus constantly reminding developers of them and becoming available for all developers on the team to see as opposed to only the original developer who spotted their need.

I'd be curious to hear the opinions and experiences of other developers on the matter. Feel free to post a comment about it.

p.s. if you're using the Eclipse IDE, there is a view you can bring up called the Tasks view, which aggregates all TODO tasks from your project files (or a selected subset). That can help keep TODOs at the back of your mind at all times. Of course, if you're a command line zealot, you can simply grep or rak the TODOs instead.

1 comment:

Jilles said...

I prefer using FIXME because eclipse litters code with TODOs that I usually delete but that are often left around by others. I have hundreds of javadoc TODO comments that I'm never going to address.

But the point is that 1) you realize that some kind of action would improve your code 2) you don't have the time to do anything with that information right now.

So what can you do:
1) forget about it (bad, this is what sloppy programmers do)
2) prioritize it over something more urgent (bad because you are not focused on the most important thing)
3) leave a note and maybe get around to doing it later (good)

There's no argument against 1 and 2 and most of us have more work than we can handle so prioritization is the name of the game and that requires an overview of work that needs to be done.

My code is littered with FIXMEs. Every once in a while, I use some down time to sit down and review them and do something with them. Some are obsolete, some are easy to address, and some trigger an hour of happy refactoring & testing. Point is that these little notes can lead to good things. At the very least they eventually draw your attention back to something in need of some attention or to some limitations of a solution that you probably want to remove.