I’ve just noticed that one of my practices has changed subtly, probably sometime during the last six months or so:
I always keep a to-do list during each programming episode. The list begins with one entry, describing the goal I’m working towards. And as I read and write code, new entries are added to make sure I go back and fix or refactor everything I see along the way. Until recently, those additional entries tended to describe an outcome – “split class Foo to create Bar and Xyzzy”, or “wrap x and y into a Mouse class”, for example. But recently I’ve noticed myself tending to write entries that describe the problem – “class Foo too large”, “x,y travel around together”.
I have no idea how, why or when this change happened, but I’m pleased it did. Between the time I write a particular to-do item and the time I finally get around to executing it, I may significantly change the code in that area. Or I may learn something about the code and where it wants to go next. Or the problem may disappear, as a side-effect of some other change. Either way, the solution I might have on my to-do list has a chance of being inappropriate now that the code and I have moved on. So by listing the problem as I originally saw it, I’m giving myself a much better chance of creating the right solution for it – because I’m deciding on that solution in the presence of the full facts.
I’ve recently been re-doing a few kata that I first tried a couple of years ago. I’ve noticed that my results are dramatically better now, mostly I think due to delaying the moment at which I decide how to solve each micro-problem. This effect is an example of Mary Poppendieck’s “decide as late as possible” maxim. There are clear benefits in terms of the quality of my designs; and there are psychological benefits too, because I don’t have to spend time trying to remember why I wanted to do each item on the list. Everyone wins.
Dave Astels has posted a link to his upcoming article introducing behaviour-driven (as opposed to test-driven) development. As you know, I’ve long complained about the term “TDD”, and Dave’s article makes the case very nicely.
The article also provides a brief overview of rSpec, a new framework for BDD in Ruby. Great package, shame about the name (say it aloud)…
Once of my current bug-bears is the lack of design done by agile teams. I know we all chant “design is good, so we design all the time”, but in reality it just doesn’t happen. Switching from legacy habits into test-first thinking and good object design is a really hard jump. The programmers’ habits have to be turned inside out, and the focus on tests seems to me to have a negative effect. I hope the emergence of BDD frameworks like rSpec and jBehave will help to make it easier for programmers to make that transition.
Update, later the same day
Elizabeth Keogh posted a nice description on the extremeprogramming Yahoo group, showing that switching to BDD is not just about replacing “test” by “should”.
James Shore lists Five Design Skills Every Programmer Should Have. I don’t believe they are too much to ask.
When I’m coaching, I often find myself setting little 10-minute targets to help teams break old habits. Here are some of my ten-minute rules for software teams:
- check-in working, tested code at least every ten minutes;
- when pairing, switch driver after at most ten minutes;
- if a design session lasts more than 10 minutes, it must be attempting to solve a problem that’s too big to be a single chunk.
Because to make these work effectively, a number of other things have to be in place. Such as a fast build and “vertical slice” thinking.
Yesterday I was speaking to a chap who had just completed a 5-day UML course. He’s a manager, and I asked him why he had taken the course. “Well now I can at least read the designs people do on my projects. And hopefully I can now also do some design myself.”
I’ve heard these misconceptions many times before – that UML is either a design tool or (worse) a design process. It isn’t. It’s a notation, based on an underlying set of concepts. Knowing UML does not make one capable of design, any more than one can become a chef simply by recognising food types and kitchen utensils.
UML has become an industry in itself. I can understand the commercial forces that caused it to happen, but I can’t help feeling that the resulting situation contains more negatives than positives. Sure, vendors can ply standards-conformant consultancy, CASE tools and training courses, but far too many people think that UML brings an essentially creative and intellectual skill (by which I mean software design) into the broader world. “Knowing” UML does not de-skill analysis or design. Knowing the UML notation does not make one a designer. But not knowing that does make one dangerous.
Don’t you just hate user interfaces that were designed by the database guy? You know the ones I mean, where the web page consists entirely of two links to ‘create’ and ‘update’. Is it laziness? Lack of time? A genuine belief that mice think in SQL?
I had an experience a few months ago that yet again raised the question of what kind of skills are required to make XP work. I was trying to get a team to adopt TDD, and was having very little success. The reason, it turned out, was that the existing code hadn’t been written TDD. Anyone trying to add a new feature incurred a huge time penalty from trying to get to the point of being able to write simple unit tests.
So I stepped back from TDD and tried to get the team to only produce well-factored code from now on. Another failure, and this time the legacy code was only partly to blame. It turned out that only two of the fifteen people on the team really understood what well-designed object-oriented code looks like. The rest wrote working algorithmic code, and were completely blind to the duplications and strong couplings they had created. For lots of reasons, including timezone differences in some cases, it was impractical to pair with everyone to help them towards an understanding of ‘simple’ code. So I did a few public worked examples via NetMeeting, and still had almost no impact on the code being produced. I guess that refactoring is a design skill, and that it has to be taught, because most programmers don’t learn to appreciate ‘good’ code in university.