Teaching and learning design using TDD (#GOOSgaggle)

On Sunday Gojko Adzik and I joined forces to run an Open Space session at GOOSgaggle on how we might work using TDD to improve our abilities in software design. Three things (after the break) have suggested to me that this might be important –

  • Looking at Bob Martin’s Bowling Game slides, pretty much the first slide says “here is the design”, along with a UML diagram. For me, that raises more questions than it solves (why is that the design? who decided that’s the design? is that the best design? are there others?) — admittedly, answering these questions are not the prime goal of this particular exercise, but I think they’re important questions in software development that we’re in danger of losing sight of.
  • Correspondingly, trying Keith Braithwaite’s “TDD as if it really mattered” exercise (in which all code to pass a failing test must be written in the body of the test method itself) forced me to abandon design preconceptions, and started a process of becoming intensely aware of what sort of decisions I was making at every point leading to a “well-designed” solution.
  • Thirdly (and to tie in with GOOSgaggle) reading Steve and Nat’s book gives a great insight into the mechanics of TDD, but it’s important not to forget that they (and Kent Beck, and Brian Marick, and Mike Feathers, to name but three…) are all highly experienced developers: their design instincts are honed from years of experience in thinking about and working with object oriented languages and patterns. There’s a strong sense of a “design compass” which pulls their coding and refactoring efforts in the direction of elegance and economy. How do we learn this design sense? And how could we teach others, and teach ourselves, in developing it?

A couple of other inputs are Kent Beck’s recent thinking on Responsive Design (watch this space for something I’m brewing with Peter Marks on this), and Michael Feathers’ ruminations on Design Sense (I don’t share his optimism that we’ll see a revival in the level of design intelligence in the development community at large any time soon).

Gojko has produced a mind-map of the wide-ranging discussion that some twenty of us held (I’ll link to it here when he’s posted it). The conversation was a good start, but perhaps we didn’t go far enough in separating teaching design using TDD as a vehicle from simply teaching TDD.

The key things I took from the session:

Teaching practical refactoring is hard (underlined by Jason Gorman’s experience at the BBC, and my reflections on some of the books and computer-based training tools I’ve seen). Part of the problem is a lack of good examples at the pattern level of design: part of the problem is that a focus on the mechanics of individual refactorings can distance you from seeing or sensing design abstractions at a larger scale.

People will only learn what they want to learn (teaching != learning): in our experience if you want to learn something, nothing will stop you.

Pairing with a view to teaching and learning is important. With a more experienced/less experienced pair, stopping after refactoring and talking about what you just did should be part of the rhythm of reflective practice. More experienced designers should do this with their less experienced colleagues as a matter of course: those less experienced should have the courage and the curiosity to ask why (for example) the refactored design is better. (As it happens I was in just this position recently after guiding a complex refactoring: we both learned from the experience of me explaining).

When you’ve refactored a piece of design or code with a “smell” into a beautiful and minimal version, you’ve also lost something: the smell. Kegan and Lahey have talked about this with reference to change and learning: here, I suggested the phrase “bottling the smell” for collecting examples of things before refactoring so we could replay or reuse the code for our own and others’ learning.

In a peer pairing situation, or indeed working individually, checklists and agreed procedures can play an important part in framing reflection after refactoring. Maybe even just run down the SOLID principles and decide which of these you’ve changed in the code, and by how much?

Pairing is important, but it can’t just be about pairing: we have to work individually on improving our design sense.

Recording a coding session with Camtasia or similar software and replaying it to oneself was an intriguing suggestion which I’ll be trying out (like a musician practicing in front of a mirror).

The requirement to talk about and teach design principles improves our abilities as designers (this is a common experience of those who teach anything).

There’s no shortage of sources for good thinking in design. Most of these are books, some rather old now. Use them.

Review design principles and try coding strictly with reference to some of these (e.g. strict “Tell, don’t ask”, no getters/setters, no state (everything functional)). Restrictions release creativity, and working in this way can reveal the benefits of (for example) the Law of Demeter more powerfully than reading about it.

Anyone out there with practical experience of teaching design sense via TDD? What do you do to teach and learn design?

2 Responses to “Teaching and learning design using TDD (#GOOSgaggle)”

Add your own comment...