You’re faced with a daunting upgrade of someone else’s application. How do you get started quickly and with minimal pain? Here’s five guidelines to streamline the process.
Every developer faces a situation wherein an application requires an update—for code the developer didn’t write. For many developers, going to the dentist for a full day’s worth of drilling without anesthesia would be more welcome than working with code of dubious origin and uncertain quality.
It’s not that the other developer purposely created a hard-to-maintain application. It’s that you don’t know the other developer’s thought process in putting the application together, making it difficult for you to figure the code out without some help. This article provides some tips to ease the pain and get you started more quickly.
Avoid Getting Overwhelmed
It’s important not to become overwhelmed by the scope of a particular project. Create an overview of the application in your mind before you drill down to discover the details. Don’t immediately find a spot in the application and try to discover every intimate detail about it—you’ll become mired in detail. Frequent SQC contributor Cameron Laird looks at it this way: “I’ve given up on understanding everything. I’m content, in many cases, to maintain an application without understanding it. Sometimes that works.”
In some cases, you may not even know the language (at least, not very well). As fellow author Jim Mischel explained:
“My first programming job was with a company that provided software support for small banks. The code base consisted of a couple hundred thousand lines of COBOL, most of which was written by contractors working from an ad hoc design document. By the time I was hired, nobody working there had been involved in the initial development. To make matters worse, I didn’t know COBOL.
“I found very quickly that it takes time and study to understand somebody else’s code. In one sense, it was fortunate that I didn’t know COBOL, because that kept me from the knee jerk reaction that we all feel when we see something we don’t understand. That reaction is, “I can rewrite this faster than I can fix it.” That reaction is almost always a bad idea. I knew that I couldn’t rewrite the thousand-line COBOL program I was tasked to fix. I could barely understand what the code was doing!”
Take a little time to read through the code to judge the quality of what you inherited. In some cases, you’ll happily discover that the job isn’t nearly as difficult as you thought. Bill Schindler, software architect at Holmes Corporation in Eagan, MN, puts it this way, “There are only three types of code you’re going to inherit. The best is when the other programmer thinks the same way you do and knows about the same amount. Otherwise, you are either inheriting code from someone junior to you (in ability anyway, not just time-on-job), or from someone who is senior to you.”
Read the software’s documentation and try to match it to the application modules that are currently in place. Scanning the documentation and trying to make a quick assessment of the application is a waste of time. Spend the time up front to discover the application functionality because you’ll never understand the application until you do.
Rod Stephens, from VB Helper, puts it this way. “There are three main reasons you might need to take over someone else’s code: to fix a bug, to enhance it, or to maintain it in the future. In all three cases your goal is to understand the code as thoroughly as possibly before you make any changes.” Laird goes a bit farther, “Taking time up front. I’m really big on generations. I like to practice making an application. In the first place, I need convincing that it’s truly all there, and starting from scratch helps me with that. Also, checking out the architecture of the factory helps me get into the mentality of the workers inside.”
Look at the application from the end-user’s perspective. If possible, sit with a user and go through the things that the user does on a daily basis. Take time to play with the application and build an understanding of how it actually works, avoiding the preconceived ideas you might have had about it.
Develop a complete list of components for the application, including the hardware the application relies upon, using an Application Performance Monitoring (APM) tool. You may be surprised to find that no one actually knows what components the application requires to do its work. Of course, you don’t necessarily have to use a particular tool to get the job done. Laird adds, “I also like to get everything neatly arrayed in a Source Code Control System.”
Spend Time with the Details as Needed
Locate the areas that require change and read the comments the developer left behind. With the understanding you’ve gained from the application documentation and the overview you’ve built in your mind, you may find that the comments actually make some sense now.
However, don’t expect things to start out that way. Mischel puts it this way:
“Comments lie as often as they tell the truth. But don’t dismiss them entirely. Even if the comments don’t agree with the code, they provide valuable information. If the comments and the code disagree, then one of the following is true:
1) You don’t understand something.
2) The comment used to be correct, but then the code changed.
3) The comment tells how the programmer thought the code worked.
Any single comment by itself isn’t terribly useful, but when you take into account all of the comments in a particular module or in the whole system, you begin to understand the original programmer’s thought processes, and that can help you better understand his code.”
Use a debugger to trace through the application code you don’t understand. Go step-by-step through the code. Remember that you’re not looking for errors; you want to simply trace through the code to see how it functions. The difference in perspective is important.
Stephens says, “Use a debugger to learn what the code is doing and to isolate bugs. Set breakpoints in the code that has a problem and step through it to see what’s going wrong. Don’t just start modifying the code until you understand what it is supposed to do and what it is actually doing. It’s amazing how many people just say, ‘I bet I know what’s going on,’ and start modifying the code without verifying that their theory is correct.”
Don’t Reinvent the Wheel
There is a temptation to rip out anything you don’t understand and rewrite it from scratch. This approach normally proves fruitless and you’ll find that you miss deadlines if you attempt it. As Mischel explains, “It takes a lot less time to study, understand, and fix code than it does to rewrite it from scratch. The difference in time increases as the problem gets larger and more complex. In the five years I was working on that banking code, I don’t recall a situation in which I found that rewriting a piece of code was faster than understanding the existing code and applying a fix.”
Also, Mischel says, even poorly written code that mostly works has a huge amount of institutional knowledge and empirically derived rules in it. “Throwing out that code and rewriting it because it’s ‘easier’ is a very bad decision,” Mischel says. “By failing to understand the code you’ve lost the benefit of all that hard-won knowledge. As a result, your ‘new and improved’ implementation will almost certainly fail and will require much more debugging than you thought.”
Perform Updates When Required
While reinventing the wheel is a bad practice, sometimes an application is in such a sad state or has such a large change in direction that you really do need to be a little more aggressive. Russ Mullen, from Mullen Business Services, encountered such a project and needed to make some significant changes.
“I was working on an application with a web-based front end and SQL back end. After I had already made some changes to get it to work properly, management decided to change it to a desktop application because the in-house equipment couldn’t handle the volume of work that would be necessary.
After redesigning it I ran into a problem that required that I convert their old hubs to much faster switches, along with workstation RAM updates, and so forth. The application conversion occurred in three phases, with an upgrade to a new OS in the first phase, along with some new linkages between the main office and its satellite companies. The second phase involved creating a wealth of new data entry forms. Finally, the third phase involved creating various reports.”
Make the Process Valuable to You
It’s essential that you get something personal out of the experience so that you have an investment in the results. Schindler looks at difficult code as a potential learning experience. “People are likely to respond differently to code that’s written by someone more accomplished than they are. It can be frustrating, too, because you look at what they did and you are completely mystified. Looking at code written by someone smarter is a challenge; you get to learn something.”
You aren’t always lucky enough to work with the code of someone more accomplished than you are. Stephens adds, “If you learn nothing else from working with other people’s code, you should learn how painful it can be. I have seen projects with no documentation and fewer than 500 comments in 60,000 lines of code. Even the smallest changes took weeks because it was next to impossible to figure out what the program was doing.” If nothing else, you’ll get a lesson in the reasons to improve your own code for those who must maintain it!
Inheriting someone else’s code can be difficult, frustrating, and confusing. However, if you approach it correctly, the task of performing an update need not be hard. In fact, you might find that the learning experience enhances your skills and leads to job opportunities in the future.
Of course, working with other people’s code is also an educational process. You discover that you have a responsibility to those who follow. As Stephens says, “Have pity on those who follow you. Keep notes, write documentation, and use lots and lots of comments. I’ve actually seen projects fail due to lack of comments. This will not only help anyone who later needs to modify your code, but it will help you if you need to look at the code again several months or years from now and you don’t remember how it works.”