Section 7.7. Diagnosing Design and Programming Problems


7.7. Diagnosing Design and Programming Problems

There are several typical design and programming problems that can be avoided by using the design and programming tools and techniques in this chapter. To illustrate these problems, the three following scenarios show how a programming team can grow increasingly frustrated over the course of their software projects as a result of losing control over their source code.

7.7.1. Haunted by Ghosts of Old Problems

Many programming teams use a shared folder to store source code. Even though they are generally diligent about making backups, and everyone is careful about maintaining the integrity of the code, mistakes sometimes slip through. Despite their best efforts, the team finds that new code seems to disappear with some regularity, while defects that were fixed months ago mysteriously resurface.

At first, the problems happened because one programmer would overwrite another's changes. One programmer would copy the code to his hard drive to work on it. While he was working on his copy of the code, a second programmer would copy it to her drive. The first programmer would copy his changes back to the shared folder. But when the second programmer copied her changes back, it would overwrite the changes made by the first programmer. This caused problems that were difficult to track down; the first programmer did not realize that his code was no longer in the folder (and neither did anyone else).

This problem seemed to get steadily worse as the code base grew. After the team had to redo a week's worth of work because an entire feature was overwritten, they were motivated to search for better solutions. The first solution they tried was creating a "checkout" folder underneath the source code folder. When a programmer needed to work on a file, he first moved it to the checkout folder, and then copied it to his local hard drive. Nobody would work on the file until it was "checked in" by copying it back to the shared folder and removing the old version from the checkout folder. But this still caused problemsoccasionally someone would accidentally copy an old version of a previously checked-out file into the shared folder. Nobody would know that it happened until a client complained about the reappearance of an old bug that had been fixed months earlier. The checkout folder "solution" was not good enough.

The team eventually put in place version control software, which put the entire source code into a repository. They chose one that was made by the same vendor as their other programming tools, because it was included and installed automatically. The software forced programmers to check out the code before they could alter it and update it back in the repository, and it locked any checked-out files so that they could not be altered until they were checked back in by the person who checked them out. This was definitely better than a shared folder, but it still caused problems. People would constantly complain of leaving code checked out on their office machines, only to find that they couldn't edit important files when working from home. Occasionally, someone would go on vacation with an entire project checked out, and nobody could figure out which files she intended to check back in. And, worst of all, there were some files that everyone needed to alter all the time. Since only one person could check them out at a time, the programmers were constantly waiting for each other to finish their tasks. The integrity of their code seemed safer, but it came at the cost of schedule delays.

Had this team gone with a version control system like Subversion, they could have prevented all of these problems. With Subversion, a programmer can update any file at any time, no matter how many people are working on the project. By being forced to resolve conflicts in the latest version of the code before committing any changes, he can prevent old code from leaking into a new build. By running the unit tests afterward, he can ensure that the build he is checking in works properly and that no defects have been accidentally introduced.

7.7.2. Broken Builds

Most programmers on the team know that they need to unit test their code. And when it comes time to do it, they try to be as thorough as possible. Before a programmer delivers a build to QA, he goes through each feature and clicks every button and UI widget to ensure that they seem to work. The programmers always make sure to take at least a few hourssometimes an entire dayafter the software is built, making sure that it works.

But all of that effort does not seem to matter. No matter how hard the team tries, the lead programmer always seems to get into the same argument with the lead tester in the status meeting after the first build of a project is delivered. The lead tester reports that the tests had to be halted because some basic functionality is missing or broken . The programmer explains that the entire team took a lot of their time to unit test the build, and that everything looked like it worked. The QA lead explains that this clearly wasn't enough, because the software is too broken to be tested. The programmer gets exasperatedisn't it the job of the QA team to figure that out and tell them what to fix? In the meantime, the testers have to sit around and wait for the new build, and their entire schedule is blown. There never seems to be a solution, just a lot of work to try to get the build good enough for the testers.

A software tester will often find defects that slipped past the programmers, because her test strategy causes her to take actions in the software that require many different units in the code to work together. Had the programmer built a unit test suite that thoroughly tested each of these units, he would have caught many of those problems before they ever reached the QA team. More importantly, if the programming team adopts a test-driven development strategy, each programmer will be clear on exactly where his responsibility lies in verifying the quality of the software. The team will know that they test each unit, letting the testers concentrate on verifying that the requirements have been met.

7.7.3. Spaghetti Code

Maintaining old code is the least desirable programming job in many organizations. Code that was patched by a dozen different developers over the years seems to be held together with the software equivalent of duct tape and paper clips. With each successive version of the software, certain aging functions just seem to get longer and more convoluted. Trying to track down bugs is a tedious and frustrating task, and even the simplest modifications can be daunting.

In an environment where aging code has turned into a twisted mess of complex and tangled execution paths, loops, blocks, and patches, the team is usually at a loss. Everyone recognizes that it's a problem, but the only solution that anyone ever suggests is rewriting some, or even all, of the code. Sometimes a rewrite is justified by upgrading to a newer version of a language, programming tool, IDE, database, or operating systembut the team knows that the only reason the idea has merit is because the old codebase has essentially become unmaintainable.

The programming team can make maintenance of such difficult code much easier by introducing refactoring. Any time a programmer encounters a twisted, tangled block of code, she could take the time to refactor it into a much more manageable block before attempting to do any work on it. Not only would refactoring make each individual maintenance task easier, but eventually a large portion of the code could be detangled so that it is approachable and much more easily maintained. Unit tests can be used to ensure that the behavior of the software does not change during the refactoring steps.



Applied Software Project Management
Applied Software Project Management
ISBN: 0596009488
EAN: 2147483647
Year: 2003
Pages: 122

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net