Achieving Better Software Code Quality

Code Quality. Have you achieved it. If yes – Congrats and bi. If not read on.

Achieving Code Quality is the holy grail of software development. We feel it deep inside us. We know its there somewhere but alas we are not able to get to it. So what is software quality and why is it so difficult to achieve?

One project I worked on management told us to build “a zero defect system”. I laughed because knowing the schedule and chaos on the project this was as good as finding a real superman and then asking him for a ride to the moon.

So what is Code Quality? Is it code which produces very low number of defects or is it  code that is well documented or code that has a good design behind it or is it a measure of how well you have unit tested it or is the pretty/well-formatted looking code.

Quality code can be achieved by following a few basic principles:

  • Think about what you are building and why and for who. And think through this many times.
  • Think about the design you want to put in place after you have answers to the earlier principle.
  • Communicate often and break unnecessary communications walls. Let everyone feed on the information. Let no one be the guardian of information. This is especially true when gathering and communicating requirements.
  • Your code is not complete without unit tests.
  • Your unit tests are not complete if you only exercised the happy paths. Thus your code is not complete too.
  • Have you followed well established design patterns?
  • Does your Code Smell – http://c2.com/cgi/wiki?CodeSmell
  • Classes, variables and methods are named with self documenting names.
  • Conduct early design reviews.
  • Review your code.
  • Re-factoring is your friend.
  • Plan for extensibility.
  • Ensure you do not incur technical debt – http://bit.ly/N6IHm .
  • De-link yourself from the code.

The last principle might look strange here. But think about it. Software development is all about people and how well our internal egos interact with others. Once individuals write the code they unconsciously feel that the code is a reflection of their intellect. Any criticism of the code then becomes a very personal matter. That is why I encourage early design/code reviews. Then its everyone’s ideas and not just one persons.

It might seem like a lot of work to implement these principles, but I am reminded of the following excerpt from – http://c2.com/cgi/wiki?CodeSmell

Highly experienced and knowledgeable developers have a “feel” for good design. Having reached a state of “UnconsciousCompetence,”
where they routinely practice good design without thinking about it too
much, they find that they can look at a design or the code and
immediately get a “feel” for its quality, without getting bogged down in
extensive “logically detailed arguments”.

My thought is that – Each and  every developer needs to strive to attain UnconsciousCompetence. Only way you can achieve that is by following the principles above and making it part of your being.

Can we really get to a zero defect system? I have yet to be part of one and I think its impossible. So rather than trying to build a zero defect system lets try to build a system with reasonably low number of defects, which has well-documented code, consistent coding guidelines, unit tests that achieves maximum code coverage. So here is how I define quality code.

Quality Code is code that has a well thought of reason for its very existence, is backed by a solid design, is testable, has repeatable unit tests, is self-documenting and has extensibility built into its very core.

To achieve good code quality everyone has to play their part.

  • Management
    • Build and maintain an environment in which the team has the highest probability of success.
    • If you do not understand technology do not ask the developer to get it done in 1 hour.
    • Ensure that a simple, repeatable and well defined development process is followed. I prefer Agile methods and practices.
    • Encourage collaboration between all players.
    • Break down communication barriers.
    • Realize that LOE’s are only guess-estimates. They have no reason to even exist.
    • Realize that creating repeatable unit tests is a coding task and often takes a good amount of time.
    • If you have a QA team that does formal testing, make sure they have defined processes in place. Have them hook into the development process early on. The more time they spend on the domain the better prepared they are to create test cases that have maximum coverage.
    • Invest in methods to gather project statistics. Define them and gather them diligently and continuously. Never use them against an individual though.

  • Developer Responsibilities:
    • The next time you check in some code without design or unit testing realize that you have just checked in code whose quality is suspect.

    • Ask for a requirements document (use case, user story) that is not in an email or in your voice mail.
    • If requirements change during construction and someone comes to you saying “hey remember last week we talked about this…now they want it differently”. Stop any urge to begin changing the code. Ask for the change to be formally included into the schedule and prioritized.
    • Write repeatable unit tests. Use JUnit or any other framework you want. But use something.
    • Have you heard of Continuous Integration!
    • When unit tests fail you are supposed to fix them.
    • Think TDD (Test Driven Development).
    • Have your peers review your design and code. This not only helps in improving quality by finding issues but also allows acts as a knowledge sharing mechanism. So if your developer is kidnapped by Martians then you can rely on the others who have some idea of that code.
    • If you think the LOE was not enough tell your project manager as soon as you realize that.
    • Look at defects your testing team finds against your code as a positive thing. That is one less defect in production.
    • Never leave performance to the end.

  • Testing Responsibilities:
    • Understand your requirements very well. You have the task of matching the requirements to what was built. So your job is very important. It’s the last sanity check before the client gets hold of the software.
    • Write test cases.
    • When you have requirements questions its NOT OK to ask the developer. Try asking the analyst or whoever is responsible for gathering the requirements.
    • Don’t let a developer walk you through testing scenarios. It’s your job to come up with those in your test cases.

Your value is not just in getting the work done but it’s also in how well you approach your work. And quality will follow.