Where do you find time to fix bad code?
Out Of Date Warning
Languages change. Perspectives are different. Ideas move on. This article was published on April 2, 2013 which is more than two years ago. It may be out of date. You should verify that technical information in this article is still current before relying upon it for your own purposes.
Bad code. You’re stuck with it. Lots of it. Over time, one small hack has led to many. Before you know it the technical debt in your application is stacked to the ceiling. It’s hard to make heads or tails out of things. How can you fix it? What can you do?
Over the past few days I’ve been working on fixing small bits of applications from years past. Though none of them are what I’d consider “horrible legacy code”, all of them are neglected but critical aspects of our product delivery cycle. One app in particular showed signs of the times it was written: in a time before PDO, before object oriented PHP, before the mysql_* group of functions was deprecated.
And amongst the end of a quarter and the meeting of quarterly goals, I found a few moments to improve these apps. How did I do it? And how can you do the same thing? Here’s a few strategies.
Use thinking time as tinkering time.
All of us have to think in our jobs. The work we do is complicated and filled with challenges. This is hard for non-programmers to understand; they think what we do involves banging against a problem until it’s solved. But we know that many of our best ideas come when we’re not working on the problem itself (that pesky subconscious).
So do yourself a favor. Step away from the problem. Go do something else. What else? That code you thought needed some love? Go work on it. Refactor a function. Write tests for a class. Do something that improves the quality of the code and let your subconscious work on your problem. Find the solution in the middle of the process? Just stash the unfinished changes in Git and go back to your task. Come back later, pop the stashed changes and finish.
Pad your estimates.
Code spends 80% to 90% of its life in maintenance. With that kind of time, it’s almost certain that you’ll work on most if not all of the code in your organization at some point (if your organization is relatively small). And chances are almost as good that your boss will ask you for an estimate for implementing a change.
Now, when my boss asks me for an estimate, she usually expects an answer of “days” or “weeks” (we work on big projects). But even if your boss expects answers in terms of hours, you can pad that a little bit by adding an hour here or there to fix things you know need to be fixed, but haven’t had the time.
Of course this has the drawback that if the estimate you came up with turns out to be woefully inadequate for the work you’ve been asked to perform, you’ll be unable to do the fixes you planned. And, it has the unpleasant possibility of discovering that your changes created a bug unrelated to what you were tasked with doing. Still, lumping small maintenance tasks in with larger behavioral or functional tasks is a great way to help improve the code over time.
Use the down time in between projects.
Most of the time projects have a little bit of downtime between them. Your boss has taken the work you did but not assigned you a new project just yet. Instead of using that time to close bugs and attend meetings (or just take a breather between rushes), make that time productive.
Grab something you’ve been meaning to fix and fix it. Write a better algorithm. Develop a test. Whatever it is, make sure it’s small and you can do it in a couple hours. This is a great option if you work in a client shop since you’ll be changing projects pretty frequently. Use the downtime to make the company’s code better.
Success is in the small wins, not the big ones.
In life, in business, and in software development, success doesn’t come from big wins. It comes from small ones. It comes from the rewritten algorithm that performs better. It comes from the clarified API that makes more sense. It comes from the interfaces you implement when no one is looking, but allow for the implementation of a new type of data storage system or a better cache.
Every small improvement that you can make to the code offers hope that the code will be better, easier to maintain and simpler to understand in the long run. It’s easy to think you’re powerless to act, when the problem seems huge. But break it down, not into modules and components, but into small functions and little routines. Make the one in front of you better. Then the next one. Before you know it, you’ll have touched far more code than you ever imagined. And the code will be better for it.