There are many design steps in XP: Release Planning contains elements of design, as does Iteration Planning. In addition, we also recommend the Quick Design Session. (See Extreme Programming Installed for more on this.) Moreover, XP practitioners in fact design "all the time", using the practice of Refactoring. (See Martin Fowler's excellent book, Refactoring, for comprehensive coverage of this topic.) Our purpose here is to discuss how some simple rules, applied locally, can produce a design which is globally of high quality.
My thesis rests on two assertions, which I'll offer without much justification. A program will be recognized as having "good design" insofar as it exhibits these characteristics:
This view may be somewhat controversial: I am in fact asserting that any highly modular expressive implementation will be perceived as reflecting good design. At some later time, perhaps I'll try to justify this view. For now, please grant the notion, at least tentatively, and come along. The rest of the article may be even more controversial: I'm suggesting that a few very simple rules can bring about good design. I'm suggesting that good design is an emergent property, given the application of these simple rules.
Some time ago, Kent Beck offered the following "rules" for simple design. In priority order, the code must:
These rules are frankly subjective, at every level. We need to have the right tests to be sure that the code still works; we need to define for ourselves what duplication is; we need to be conscientious about what ideas need to be expressed and how to express them; maybe we even need to know when classes and methods are minimized, whatever that means.
OK, they're subjective. Let's embrace them, and think about what the rules mean to us and what they'll do to the code as we apply them.
Applying these rules, we wind up with compact, modular code, expressing all the important ideas of the system. We wind up with "good design".
In a posting on the Agile Modeling mailing list, Alan Shalloway of Net Objectives, proposed some alternative rules:
Alan comments:
"If you look at design patterns, you can see that most of them follow these rules. High cohesion and loose coupling can often be achieved by decomposing your problem domain with the distinctions of commonality / variability analysis. That is, find how things are similar and then find out how they are different.
"The other thing I like about this set of rules is that they are easy to teach and understand. Cohesion has to do with clarity. Method cohesion means a method is focused on one purpose. Class cohesion means all of the methods in a class are focused on one larger purpose."
Since, as I asserted at the beginning of this piece, I believe that high cohesion and low coupling are the essence of design quality, I have every confidence that applying Alan's rules will surely also result in good design.
My suggestion is that both these rule sets, and the underlying premise that modularity leads to good design, are worthy of reflection. Whether we use one rule set or the other, I'm confident that we'll find that these simple rules do cover a wide range of what we ourselves mean by "good design".