Some days ago, I was reading an excellent book that was recommended by a colleague/mentor. The book was called "Pragmatic Programmer" (written by Andrew Hunt and Dave Thomas), and one story in the book really stood out for me. It was titled "Don’t live with Broken Windows". The story was based on a crime-related study that showed that when police tackled seemingly small crimes (such as broken windows, graffiti, etc.) more aggressively, the rate of big crimes also reduced as a result in those neighbourhoods. People living in those areas felt a heightened sense of pride in their neighbourhood as a result. The authors then draw an excellent analogy to the software industry and to the fact that when quality of software goes unaddressed, even seemingly small problems escalate to large problems eventually, and the team morale also begins to suffer.
Sometime ago, I was an unfortunate participant and witness in one such project and have learned many valuable lessons from that experience. I went into a project that was only three months from implementation (after nearly 4 years in the works), and several features were either still not implemented still or were not working correctly. Because of poor leadership (and due to some bad hiring decisions), almost every member of the original team that had helped to design or develop major portions of the system had either quit or were let go. The project was nearing its implementation date, and the project owners were anxious to get this done. And so, a bunch of us went on a "rescue mission" to fix things. But, we were in for a huge surprise. We found it nearly impossible to implement the missing features or fix any pending defects for several reasons. We noticed extremely hard to read the existing code (some PL/SQL procedures were up to 5000 lines long) filled with hard coded numbers and dates and it was hard to tell their significance without any comments as well. There was also very poor error handling, error logging and other debugging mechanisms in the system making it harder to troubleshoot problems still. Compounding this situation was the fact that most documentation around the project had become out of date. The code really needed heavy “refactoring” (clean up), but given the looming deadline and other constraints, the software project management team advised us to go ahead and just "ram" our fixes in. So, we did our best, and did implement the system in time although the whole experience was most stressful for everyone involved.
Nothing diminishes anxiety faster than action. ~ Walter Anderson
After this implementation, I couldn’t help but wonder after about my many findings during the project, especially about the huge number of clues that had emerged even at the beginning when things appeared to be going smoothly. For example, looking at the defect logs, I could almost trace a “history” of the attitude of the original project team as many team members seem to have operated under the belief that unless a defect was in the area of their direct responsibility, then it was not something they needed to be concerned with. This approach was used to successfully ignore many issues (including some core architectural problems) which were in areas used by everyone. It was not long before these problems grew many fold very quickly and started to impact almost everyone involved. The team members then started to point fingers at each other instead of collectively working together to solve these problems. No one felt any pride about what had been accomplished overall as a result even though many members of the team sacrificed so much of their family time to help get this project completed.
For me, this project will always stand out as a perfect example of what happens when software teams do not place emphasis on code quality right from the beginning. It helped highlight the importance of keeping both the requirements and design documentation current, and the value of unit and automated testing mechanisms. Most importantly, this “fiasco” helped highlight the fact that software projects should provide an atmosphere for people to speak-up and challenge approaches to all aspects of a system being developed (even on areas that may not be strictly in the realm of responsibility for some team members). When such practices and approaches are adopted, software teams should be able to enhance or fix any problems in software much more quickly.