For years developers have been applying (and
usually misapplying) building construction as an analogy for software
development. Lots of smart people (like Jim Shore)
started calling them on this. Over time, some other people described software
development as analogous to the design/architecture phase of physical
construction and that our true construction phase is compilation.
Sometime last year I realised that I was
calling non-TDD development "freehand" programming and recently I saw
a connection between what I thought of as freehand software development and and
architect creating a freehand sketch.
TDD-style software development is analagous to
an architect using drafting tools to build construction quality blueprints
while freehand programming is like an architect quickly creating a sketch to
try out or share an idea. The architect would never want to construct a
building based on a rough sketch the same way I would never want to deploy
software that I hadn't developed via TDD.
While working on a spike a tend to not worry
too much about adhering to any specific Agile practice. My goal is to get
something that barely works and that can even mean that it crashes when I click
on the wrong button. Developing freehand works just fine because I don't care
about the reliability or flexibilty of the spike I am creating. An architect
draws freehand when he doesn't care that his corners aren't square or his
measurements aren't true.
This idea of using tools to ensure that my work
is correct enough to use in the real world is the core of the freehand versus
TDD analogy.
I'd love to get feedback on this concept (and
my presentation of it). I'm hoping to add this metaphor to my "Why TDD is
worth learning" discussions and want to know if it will help me communicate
about TDD better.
I expect some BDD guys to comment that I am
leaning on the "Test" part of TDD when that is not what TDD is really
about. What I am really trying to convey is that TDD (and other Agile
practices) yield high quality results.
I like something that I believe you once said to me: TDD would still have value even if somebody came along at the end of the day and swept away all the tests that you had written.
I do generally find that testable code is of higher quality than untestable code. (There are counter examples, but I think there is a correlation between testability and quality.) I certainly found that my coding style changed as I was learning TDD. More recently, I find that I don't often write unit tests (even in places where it would definitely help me). Still, TDD has had an obvious impact on the code that I write. I think many programmers could benefit from thinking from a test-oriented point of view.
In terms of design, I think that unit tests act as a sanity test. By actually trying to exercise the class under test, the developer will see the class from a new perspective. Ideas that seemed good from the inside of the class might turn out to be bad ideas when viewed from outside. Bulky classes create bulky tests, and bulky tests can be easier to see.
To tie this back to architecture, I think of unit tests more like CAD. An architect who is restricted to paper will have a harder time "seeing" the building he is designing. On the other hand, an architect with access to CAD software can instantly grok the entirety of his design. Anything that appears out of place will be obvious. The same is true for unit tests. Tests make it easy for you to think of a class as a whole, from the outside. This perspective shift is the key.
Posted by: Dan Yankowsky | March 09, 2010 at 07:51 AM