|
Sitting next to me on a flight last month was a
developer from a large multi-national. They do Agile
“around the clock”: The team in Toronto spends the day
coding and unit-testing a task or story. When they go
home in the evening, their teams in India and China
pick it up for testing. The next day Toronto fixes the
bugs, and the cycle continues until eventually they
declare victory.
“It seems to work well, but sometimes I feel like
we're rushing it,” he said.
One of my habitual red flags just went up. “How do
you like the code's quality, and its design?” I asked.
As I anticipated, he grimaced. “Not wild about it.”
And then he admitted, “We rarely go back to improve
tested code.”
That reminded me of my developer days back under
the Waterfall regime. We rarely went back to improve
tested code either, but at least we had the time to
produce (what we thought) was good, clean code.
Since most development tasks took a couple weeks or
more, we had some cushion, some buffer to spend on
technical quality. (Let's ignore for a moment that the
clean code standards of the 1990's were rather unlike
today's.)
Agile teams have a whole different experience. The
whole team (not just developers) takes charge of
starting and finishing a piece of work so it's
potentially shippable. To that end, they define “done”
criteria for stories.
My seatmate's team has a customary definition of
“done”: a story is done when it passes the unit
tests, customer acceptance and QA tests.
What their definition doesn't cover — and
statistically, your team's definition of done doesn't
either — is for the story to pass the developers'
professional judgment tests. In other words, for the
story's code to be clean, not just running.
There's an implicit assumption that developers would
write good, clean code. This assumption is based on
knowing them to be capable professionals and the
existence of the practice called “refactoring”.
The developers might be refactoring their code as
part of the TDD cycle (if they do TDD, which is not
the case for many teams). Maybe they pre-factor large
messes before taking on new stories. But there's
nothing in the team definition of done that
constrains them to do so.
All we have is the implicit assumption, or blind
hope, that they practise their TDD and refactoring
diligently and mercilessly enough to produce clean code.
This is a particular risk for Agile teams that still
espouse the classic management attitude of assigning
work to task experts (“silos”). Each person lives in
the same component of the codebase for a while, and
there's little sharing or review of their code. Have
you ever had the pleasure of inheriting or having to
fix somebody else's code? Did you find yourself
thinking, “That's what they wrote? It's terrible!”
Since in Agile the team is the “production unit” that
delivers stories, effective teams naturally practise
collective code ownership: No piece of code ever
“belongs” to any one developer.
Individual contributors who form a cross-functional
Agile team know to define “done” to include the various
functions and roleplayers. And so customers and testers
review the work product for correctness and identify
deviations. But what's the developers' part in “done”?
Checking in unit-tested working code.
Anytime your developers let slide a code smell —
whether they're aware of it, or worse, they're not —
that's a cost you'll pay later. We call that technical
debt. It's not the developers but the whole team who
eventually bears that cost by going ever slower.
That doesn't mean you should always produce perfect
code. You can take on technical debt judiciously, but
that decision has to be made consciously and by the
entire team. This ties into my Contextual
Craftsmanship concept (see my article in the Cutter IT
Journal).
If you agree with that, you only need to expand your
definition of done with one question:
“Is the code as clean as we care to have it now?”
Copyright © 2010, 3P Vantage, Inc. All rights reserved.
|