My understanding is that the concept of simple design is Kent Beck's invention, but I've not found a definitive answer yet. I reference the Ron Jeffries XP series book as the first published place I could find it (but the material on the C2 wiki predates this). I also wrote about these four rules as a chapter in Uncle Bob's Clean Code.
The notion of "simple design" is often interpreted as YAGNI ("you ain't gonna need it"): Build only what the customer asks for--don't add bells and whistles that they don't need. Or, from a design perspective, don't build complexity into the system where it's not needed. Don't introduce abstractions unless you have a valid need, and don't build the all-encompassing infrastructure or design that will support every possible feature that could come along.
But my definition for "simple design" has always been these four rules that I learned while at one of the Object Mentor XP Immersion classes, way back in 2000-2001. The Immersions were led by Uncle Bob, Ron Jeffries, and Kent Beck, with a few of us fortunate lesser Object Mentors helping out as table coaches. These were some of the most entertaining sessions I've ever attended.
The four rules of simple design speak to specifics--while YAGNI can be understood in a broad context, here we are specifically talking about systems design. The rules are in order of importance, hence the numbering, and you'll note that the last one, i.e. the least important, is the rule that most closely speaks to YAGNI. More important, then, are having as comprehensive tests as possible, minimizing redundancies, and coding clearly.
My contention is that if you knew nothing about classic concepts of good design, such as the single responsibility principle, the dependency inversion principle, design patterns, and other heuristics, you could still get there by following these four rules. When explaining these rules, Beck talked a lot about the notion of emergent behavior--that you can get a holistically positive result just from applying a very small set of simple rules at the individual level.
I've done that experiment a couple times in reasonably-sized subsystems (a few dozen classes): I've followed TDD (test, code, refactor), and during the refactor step only considered rules two through four, trying to pretend that I didn't have a good background in OO design. Then I've gone back and sketched a model of the design in UML. Both times, I've been pleasantly surprised, having produced a design that looked elegant but not complex.
You don't have to throw away your exhaustive knowledge of design principles when using simple design. Instead, reconcile what you produce with the rules, and be willing to change your design principles if simple design suggests there's a problem. Try it!
I like how the fourth rule is stated here: http://c2.com/cgi/wiki$?XpSimplicityRules. The phrase "minimizes the number of classes and methods" has always bothered me because it can be abused so easily, or misinterpreted as an encouragement to create large, monolithic classes and methods.
ReplyDelete"Has no superfluous parts" fits well with the concept of Simple Design and doesn't have the pitfalls mentioned above. In fact, I really like the way c2.com lists all four of the rules:
1. Runs all the tests
2. Expresses every idea that we need to express
3. Says everything once and only once
4. Has no superfluous parts
There were two versions of the four rules in Kent Beck's first book on XP. With Paul Nelson's comment, I think both versions are now on this page.
ReplyDelete