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.
Tomo Lennox · August 31, 2015 at 2:07 am
If someone could really understand the customer’s needs and image the a system to implement them and understand the strengths and weaknesses of the solution, it would be much better to have them share what they know with the developers, who could do a clean design to the clean requirements. But now that I have been through this 100 times, I no longer believe that anyone is smart enough to do the job. I now believe that the requirements are just a pretty good guess at what is needed. The reason that design emerges is because of the feedback loops you get when you build stuff that you can share. The customer’s eyes glaze over when they loop at the 134 page requirement spec. They can sign it, but they can see it in their heads. But as soon as you show them the part of the solution, they understand a lot better, and they tell you what is wrong with what you build. Then you get smarter, and then your design gets better. Something similar happens when you show your piece of the solution to someone else on your team. Emergence is all about things you thought you knew that just ain’t so.
I agree that bad designers can “emerge” bad designs, and I agree that good designers would do better if you could give them good information up front. I have just lost hope that anyone can specify a system that they can’t see working.