« Making Your App Infintely More Testable | What are your most challenging object oriented progrmming questions? » |
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.
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.
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.
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.
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.
Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP
Posted on 4/2/2013 at 7:00 am
Nikhil (@nikhilcutshort) wrote at 4/2/2013 10:31 am:
Is their a filter for bugzilla that tracks such ‘code that needs improvement’? This would also be a great way for contributors to jump on board.
Aki Sasaki wrote at 4/2/2013 5:40 pm:
Any chance you can change your rss settings?
I keep getting blog posts from you in Thunderbird from planet.m.o, read an interesting headline, see two lines of text followed by a […], and I delete it.
Simon wrote at 4/2/2013 7:03 pm:
@Nikhil – I’m not sure that anything marked as “bad code that needs fixing” is a good candidate for new contributors, given that such code is in many cases going to be some of the hardest code for an outsider to get into.
Brandon Savage (@brandonsavage) wrote at 4/2/2013 7:17 pm:
When I make my RSS feed available my content gets stolen from Chinese content thieves.
Martin Hlaváč (@m_hlavac) wrote at 4/7/2013 9:00 am:
I’ve found out that what works best is to say that you can do this new module, but it needs already written old system to work. In this case i must look at old system and write tests to be sure that new system works as well.
If someone asks if i can skip the test phase i say no and even if i could, it would leave the application in unkown state which would eventually cause new bugs for clients.
Hikari wrote at 4/11/2013 6:11 pm:
lol another great post! :D
Before talking about fixing bad code (I’d call it enhance software quality…), we must understand their cause!
1) Evolution. We evolve, today we’re better professionals than 1 year ago. Of course what we do today is better than the past, at that time we did things that now we know were wrong, or we learned better ways to do it. Community also evolve, what’s best practice now will be rejected soon, and in web dev that happens damn quick!
2) Time. The far biggest reason to make things bad is lack of time. Time to plan, time to think, time to redo. Instead of taking the time to do it right, we do it with what we have at hands. Or when development advances and with more info we see that some decision wasn’t adequate and must be changed, but we don’t have the time to rework and must leave it that way.
I personally rarely enhance quality on something that’s working. That was the best I could do that time. I’d rather make something new than just aim perfection.
Also, remember that if you don’t have a very good test units set, changes may add unoticed errors. And if your team happens to not have a serious configuration management, you may not even be able to track what and when an error was created!
I think it’s way better to just plan the software life cycle, invest what’s worthy to make it reliable enough during that time, then remake it totally using the experience of its use, then keep making small investimens to make it live longer and also adding risk.
@Nikhil IDK about bugzilla (I don’t like software management tools that are focused on handling bugs!), but in Redmine we can just open an Issue of type Chore and put it in a future version.
« Making Your App Infintely More Testable | What are your most challenging object oriented progrmming questions? » |