The Ugly Truth About Emergent Design
If the 2nd D in TDD is design, then we’re talking about emergent design. The tests drive the design, which emerges from thin air, and step by step reveals itself in all its glory.
Emergent design has got to be superior to upfront design, right?
Well, it depends.
If we’re doing a design up-front, we need to take into account all the needed requirements from the solution. We need to understand all the interaction between existing subsystems and the module we’re developing. And to make it also testable, we need to think about how to test it.
All things considered, these activities are not inherently bad. We need to think before we run.
So how come Design Up Front has so much bad reputation? It’s really the BDUF that does. The BIG design up front, where we put a lot of work up front, which gets thrown away when new information or requirements appear.
It’s about the up-front waste, and it relates to the final result.
Emergent design, however, takes into account that we don’t know everything at the beginning. Throw in the incremental tests, which are usage examples, it grows out of the up-to-date examples we need.
So emergent design is not all that bad, because it saves us the BDUF wasted time. It helps alleviate the wasted time on non-relevant information.
Now, let’s assume that there isn’t much waste. Understanding the requirements is still important, we still need to do that. Getting a better understanding of the system is probably more valuable than discovering the requirements incrementally.
Is the emergent design better than its prescriptive design evil twin?
Design does not emerge all by itself
We forget there’s an additional ingredient. There are people involved.
The design is as good as the designer. If I’m a bad designer, I shouldn’t expect a wonderful design to emerge. If I’m an experience designer, I’d probably get the same level of quality of the design of both the prescriptive and the emergent.
We seem to confuse things. Like, when we confuse testability with good design. Since TDD is testable by design (pun intended) and produces emergent design, we assume the result is better.
We can design a crappy solution which is fully testable. In fact, if we are so bad at design, it’s better to do an up-front one, review with people who know better, and get directed onto the right path. Much better than discovering that, after we’ve built our crap-fest.
TDD is a tool, and not a magical one. If we are good designers, it will produce a good design incrementally. Without proper use, it’s going to get ugly.