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
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
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
(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
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
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.
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
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.
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 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.
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.
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
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.
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.
Tests extends this reasoning. User tests provide another line
of testing which helps detect problems early.
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.
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.
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.