I’ve written a chapter in my book on The Relationship Between ATDD and Design Patterns. Essentially, ATDD provides us with quality acceptance criteria in the form of test specifications. We can use these to design our code from a behavior point of view instead of from an implementation point of view.
Doing this makes for more testable code, a quality highly correlated with other code qualities we want – strong cohesion, loose coupling and no redundancy. Design patters provide us with a method for combining these high quality objects together through the Gang of Four’s mantra’s of designing to behavior, using variation and encapsulating variation – in this case variation of type.
In the Agile world where requirements evolve, ATDD and Design Patterns Thinking work together to enable emerging designs from emerging requirements.
As consultants, we are often asked to review the work of others. One of the things we review is the quality of the design of some part of the system. Is it cohesive, decoupled, non-redundant, encapsulated, open-closed, and so forth? Often the developers understand and agree that these qualities are important, but they are not certain they have achieved them adequately.
I often start like this, “I don’t know. Can you write a good test for it?”
With a name like TEST-driven development you’d expect TDD is mostly about testing. Especially when the end result is tests. In our book Design Patterns Explained we discussed how testability (how easily code can be tested) is an intrinsic property of software and is highly correlated with good design. This is why the 1st mantra of design patterns is to design to the behavior of the objects being written. These behaviors being described as tests.
One of the characteristics of good design is that it is modifiable with less effort than poor design. So testing first give us both better design of the code & increase its sustainability-enabling emergence. This is the big difference between test-FIRST and unit testing.
But we now have the added burden of the tests which often add to maintenance costs. The cause of this is insufficient focus on the quality of the tests. An ideal test will validate only one behavior. The intent is to decouple the tests so that when one behavior changes only one test needs to change. This requires attending to the coupling of tests as future enhancements are made. Coupling of tests inform coupling in design.