Agile Zone is brought to you in partnership with:

Allan Kelly has held just about every job in the software world, from sys admin to development manager. Today he provides training and coaching to teams in the use of Agile and Lean techniques. He is the author of "Changing Software Development: Learning to become Agile" (2008) and "Business Patterns for Software Developers" (2012) and a frequent conference speaker. Allan is a DZone MVB and is not an employee of DZone and has posted 85 posts at DZone. You can read more from them at their website. View Full User Profile

Things to do to improve code quality

  • submit to reddit
As I mentioned a couple of posts ago, I was recently out in Oslo teaching a course on Lean software development. One of the points I make is: Quality is free (or at least cheaper) provided you invest in improving quality.

This section of the course included an exercise were I ask the participants to think of things they could do to improve code quality. On this occasion the exercise went particularly well and resulted in the list in the picture below:

Lets run through these one by one - not necessarily in the order on the sheet:

Test Driven Development: if there is one practice above all others which contributes to better code quality and fewer bugs it is TDD. On the plus side it can be used on any type of project, Agile, Waterfall or other. Its roots go back a long way but it was a forgotten practice until XP resurrected it. When run as part of a continuous integration cycle with frequent automated builds and tests the practice is Unit Testing on steroids.

However it doesn’t just happen by mandating it so. Most developers don’t know how to do it, they need training and help (coaching) to do it. Even then it is going to be a learning experience, don’t expect it to become prevalent overnight.

(And before you say “But we have a legacy system with 1 million lines of code so it won’t work for us” please read my implications of the power law.)

Acceptance Test Driven Development (ATDD) is the next level up from unit test based TDD. Here those making the requests for development not only specify their acceptance criteria but do so before any development happens, and do so in a way that they can be automatically executed. In many cases professional Testers need to work with the “Customers” to create such tests.

Continuos Integration (CI): This is a valuable practices on its own - making sure code builds and new code doesn’t break anything that already exists. When coupled with TDD and ATDD to created automated, repeatable, test suites, it is an order of magnitude more valuable.

Pair Programming: The controversy over pair programming seems to have died down, but then so too have examples of people actually doing it. A shame really. It is instant code review, it is two-heads better than one (think of commercial pilots or surgical teams). It also allows developers to focus intensely on the work in hand - few distractions from telephone calls, e-mails, SMS, and all the other rubbish that distracts us so easily.

Code review: The next best thing to pair programming. If people won’t pair then at least code review. Put in place a light weight process which happens as soon after the code is written as possible. The big formal process so many of us learnt about in school aren’t practical - only NASA can really afford them anyway. Instead use a lightweight process, you will get 80% of the benefit for 20% of the cost.

Static analysis tools: in the past static analysis tools have gotten a bad name for themselves. The current generation are a lot better and while they are not a true substitute for a code review (because in a code review both reviewer and reviewee learn) they are very cheap to use. Sure you might have to buy a license but once you’ve done that and set them up in the build system they run every time code is checked in and can highlight potential issues very quickly.

Coding standards: Traditionally I’m not a fan of coding standards. In my experience too many teams waste to much time debating and arguing over coding standards and when they are put in place they can be used as a tool for some developers to bully others. However, if you can overcome those problems then they have a valuable contribution to make.

Start by having a group discussion - face-to-face, not over e-mail or on a mailing list - about what could be in a coding standard. Find the areas of agreement and have three or four categories: a very few items as “mandatory”, more items as “recommended” and more as “candidates.” This third group are possible candidates for inclusion in recommended or mandatory but need some consideration. The fourth group for things you agree not to standardise on.

Then review these guidelines every three or four months. Promote some from candidate to recommended, and from recommended to mandatory, and if some aren’t working then remove them or demote them. (This recommendation is broadly in line with Les Hatton’s suggestions in Safer C.)

Then, don’t use coding standards as part of your review. Developers should follow them out of honour. But just in case you miss one, automate them. Set your static analysis tools up to run your coding standards against code which is checked in. Remove the human from the loop and remove the bullying.

Automate: In case it hasn’t sunk in yet, most of the suggestions so far can be automated, and should be automated. Not automating them means they take time to do and are therefore expensive in the long run. Automation might cost in the short run but it makes things cheaper overall.

Refactoring (& refactoring tools): The whole point of refactoring is to improve the code quality and, more importantly, the overall design. If it isn’t then something is wrong. You can, and people do, refactor without automated unit tests but this is equivalent to a high-wire act without a safety net. With the safety net in place refactoring should be a frequent activity and one which doesn’t take up lots of time.

As an old C++ hand I’m always impressed by the refactoring tools available to Java and C# developers. These should lead to more frequent, quicker and safer refactorings.

Hopefully it is immediately obvious how the above can lead to better code. Some of the other items on the list aren’t so obvious but I think they are worth including.

Show and Tell (early): maybe not immediately obvious why this one should lead to better code but it will. By regularly showing potential customers of the software what they are getting developers need to keep their code near to release state. This forces more, smaller, steps in development.

The second reason why this helps is that feedback comes more regularly. This provides positive guidance on what is going right and will point out when things are going in the wrong direction.

Finally, if developers are scared to show their work in progress to users and customers then its time to run up the red flags and look for trouble.

User Tests extends this reasoning. User tests provide another line of testing which helps detect problems early.

Similarly, working on smaller pieces/projects provides for more small steps. Before each step there is an opportunity for re-adjustment and course correction both at the work planning level and at the code level.

Finally, Team cohesion is important because without it the team are running in different directions and doing different things with the code. Part of team cohesion must be a shared view on the development objectives, the design ideas in the code and what makes for good code.

This isn’t an exhaustive list, just the ones my students in Oslo came up with; if you have any more suggestions please add a comment, thanks.
Published at DZone with permission of Allan Kelly, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


Loren Kratzke replied on Thu, 2010/06/03 - 7:00pm

TDD - Assumes that the design is 100% complete which is common in waterfall, not so much in Agile. Late discoveries, change requests, and other non-ideal realities come at double the price of the same realities when not performing TDD. Tests that pass do not prove anything beyond the fact that tests pass. Who proves that the tests are adequate or that the code being tested performs the proper function? TDD ensures only that tests are written first, nothing else.

 Pair Programming - Double the cost up front yet does not guarantee double (or even better) quality of code, and code review is still required by somebody that was not the author of the code. Deep thought is not possible with two programmers on one computer, and only works if programmers are compatible in the right ways. Good only for certain problems under certain circumstances with certain developers. Design meetings are more fruitful in this regard.

  The bottom line is that there are many types of projects and developers. The only possible wrong choice is to blindly subscribe to any single extreem methodology and proclaim that it is the only way or even the best way. It is better to think of these methodologies as tools in your toolbox and apply them in the right amounts and combinations for a given situation.


Allan Kelly replied on Mon, 2010/06/07 - 3:19am

Thanks for your comment, can I reply in reverse order?

I whole heartedly agree with your final point.  There are many different types of projects, many different type of developers and many different ways to fail. When you look at projects that work certain common patterns and practices emerge. As Tolstoy wrote "All happy families are happy in the same happy way, all unhappy families are unhappy in ther own unique way."

The greatest mistake is to blindly follow anything to the extreme without questioning it and asking "Does it apply to me?".  For that reason I often talk about Agile as a set of tools in a toolbox and you select the ones that apply.

This piece, from the picture on, is a discussion of things you could do to improve your code quality.  This is a list of tools: pick some.  Its not a comprehensive list, I ask for more suggestions, nor is it a mandatory list, its a list for you to pick from.

As to pair programming I do not believe it doubles cost at all.  On the contary, I find that pair programming enables deep thougt because it provides someone equallly dedicated to share the thinking.  True, if two developers are not compatible there will be problems, but, there will be problems if two incompatible programmers are working on the same project anyway.  Pair programming will simply highlight the problem sooner.

As to TDD assuming the design is 100% complete before you start coding nothing could be further from the truth.  Not only does TDD not assume this but it greatly assists in helping designs to emerge over time.  In the long run TDD is an essential completement to refactoring and emergent design.


Srid Chm replied on Fri, 2010/06/11 - 9:28am

Nice article and discussion

Raja Nagendra replied on Fri, 2013/09/27 - 12:30am

Root of all Evils is lack of professionalism, i.e deep respect for what we produce.. this is mostly driven by Business Ethics around keeping client happy by committing of reduced time lines, reduced costs...

Unlike in Health Industry, IT industry makes more money by not delivering now and continually saying we will deliver better next time..  

We at TejaSoft follow common sense approach, where in each of our team member is aware of where is the productivity loss, what are the recurring works... all these we automate.. We call this Extreme Automation..

I wish to see clients move towards Services 2.0 Model, where Fixed Bid and Time and Material are applied for each two weeks (Agile)..


Raja Nagendra Kumar,


- 20 Million lines of Java Code Re-Engineering our system..

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.