No Heroes in Tech Debt

Too often when I see a team trying to replace a bad/old/deprecated pattern that is widespread in a codebase, they default to what I call The Hero Solution: One person on the team goes through and fixes every case of it themselves.

This can work for very small efforts, but it’s almost always a terrible solution in larger efforts for a few reasons:

  • When the bad pattern is widespread this is the slowest way to fix it and the slowest way to get to value from the new pattern.
  • There’s nothing in this policy that stops other people from continuing to add the bad pattern. Indeed there will often be code with the bad pattern that they want to copy/paste/modify, making the bad pattern almost contagious.
  • Teammates may be working in the same areas of the codebase causing merge conflicts that slow both the teammate and the hero down.

Here are a few tips that will see better results:

Track the bad pattern

Find a way to track instances of that bad pattern over time. Often a simple git grep "whatever" | wc -l will tell you how many cases of it you have in the codebase. Check often and record the values. Whatever your strategy is, if it’s not trending toward 0 in a reasonable timeframe, your strategy is not good enough. Come up with something else.

I can’t tell you how many cases I’ve seen of efforts trending toward multiple years (sometimes as much as 10 years) as soon as I started measuring over time, determining the rate of change, and extrapolating the completion date.

If you do nothing else, do this. You’ll quickly be able to see the cost (in time) and be able to reassess the value propsition.

Stop the spreading!

Agree with the team on a policy that no new instances of the bad pattern will be added without a team-wide discussion. Add pre-commit hooks that look for new cases (git grep is awesome again) and reject the commit. Look for new cases in Pull Requests. Get creative! Without this, you’re basically bailing a leaking boat without patching the leak and you will have:

  • People that want to copy/paste/modify some existing code that has the bad pattern
  • People that don’t even know the pattern is now considered bad
  • People that knowingly implement the bad pattern because they don’t know about the good pattern.

If you can’t get your team mates on board, your effort is doomed. I’ve seen bad patterns actually trend upwards toward infinity when no efforts have been taken to get consensus or stop the bad pattern.

NB: Because of the regular human effort involved in maintaining consensus and educating and re-educating people about the goals, one of the best ways to stop the spreading is to concentrate on faster total conversion to the new pattern. Having bad examples all over your codebase works against you on a daily basis. Bad patterns are contagious.

Get your team mates involved in the conversion!

Here are a few ideas:

  • Have a rule where no modified files (or functions or modules or whatever doesn’t feel too aggressive for your team) can contain the bad pattern anymore. Figure out ways to enforce this automatically if possible, or in code reviews if not.
  • Break the work into chunks and schedule those pieces within other product work on a regular basis. This is sort of a nuclear option, but if the chunks are small enough (yet still encompass the entire scope of the conversion), you can show regular and reliable progress without stopping production work for any extended period of time.
  • Get other people to help with the conversion! If people are bought into it, there’s no reason one person should be doing it alone. Multiple people working on it (in a coordinated fashion) will reduce merge conflicts with product work, and increase knowledge sharing about the proper pattern. You may even get better ideas about how to convert.

Don’t do things that don’t work.

Stuff that doesn’t work:

  • Efforts that the team as a whole doesn’t find valuable / worth the cost.
  • Efforts that are ill-timed. Should you really do it now? Is this really the most important thing?
  • Efforts that are not tracking toward 0 in a reasonable amount of time. Partial conversions are really hard to manage. They may not be a strictly technical concern, but they are a concern for on-boarding, managing, complexity/mental-overhead, knowledge-sharing, etc. Come up with a strategy that doesn’t prolong them.

Big problems need smarter solutions!