Systematic combination of subpatterns generates design patterns

Composite patterns, such a the Bureaucracy pattern, are patterns built by the composition of other “smaller” patterns. However even usual design patterns can be considered composite patterns made of smaller subpatterns.

The goal is therefore to find out which are the main subpatterns that enable to reconstruct as many design patterns as possible.

The subpatterns

From an early analysis I believe that four subpatterns form the foundation of many GoF design patterns:

  1. Type Hierarchy and its variants (interface, abstract class, non final class…)
  2. Type Set, a set of types with no particular relationship between them
  3. Delegation and its variants (one-to-one, one-to-many)
  4. Allocation (creation of instances) and its variants

The experiment

To validate this proposal, I have coded a small experiment to generate every combination of two subpatterns out of (1) and (2) plus one relationship between them out of (3) and (4), or every combination of one subpattern out of (1) and (2) plus a relationship of (3) and (4) to either itself, or in the case of (1), between a super type and a subtype or the other way round.

For each generated combination I have automatically generated its corresponding class diagram, and grouped them together into one SVG document, converted into PDF using Inkscape. The resulting picture is available here, and you can see a partial preview below:

combinations_thumb

Results

The interesting finding is that this simple combinatorial method re-discovers 11 well-known design patterns (in the reading order of the picture):

  • Template Method (delegation to self, expecting a subtype to provide the service)
  • Composite (Considering a one-to-many delegation) or Decorator / Proxy (one-to-one delegation)
  • Prototype (creates instance of this type)
  • Bridge (one Abstraction hierarchy delegates to another Implementor hierarchy)
  • Abstract Factory (one Factory hierarchy creates instances of another (or several others) Products hierarchy)
  • … skip 4 next …
  • Strategy or State or Builder (some client delegates to some hierarchy)

Note that there are several cases where we could see the Factory Method, Adapter or Facade patterns. This would lead to some 13 design patterns out of the 23 in the GoF book.

Discussion

It is obvious anyway that the four subpatterns used here are not enough to rebuild the full set of the 23 design patterns. The Command pattern is unique in its use of a separate invoker, and the Chain of Responsibility is clearly about how handlers self-assign a given task without any centralized management. In these two examples however, the unique characteristics is not in their structure but rather in their dynamics. Sequence diagrams would be much more relevant to convey that kind of information.

The full test runs in one go in a fraction of second. The source code is available here: patternitygraphic_src, the code of the experiment is in CombinationTest.

EDIT: the plain SVG file that was generated is also available here for download:

Read More

UML is a too low level language

I recently taught design pattern to 20 of my co-workers in a kind of training session, here are some thoughts I had while preparing this presentation…

In OO you usually end up with many classes, especially when you correctly use design patterns; each class is also generally very simple and rather short. Thus classes are now in OO the equivalent of the “if-then-else-for” instructions in structured programming: low-level language elements.

Unfortunatly, UML is essentially about class-level static description (class diagram), dynamic objects interactions (sequence, object diagram). Even more OO-independent part of UML such as state diagram is still at the class level, as typical implementation using the State pattern (GoF) implies using a class for each state.

What is the higher level above the class-level ? In my opinion, it is the (design) pattern level, for at least three reasons:
– granularity: a design pattern usually deals with more than one class, so it is a natural way to talk about several classes as only one entity;
– patterns language: patterns may be solutions to solve recurrent problems, sure, but they first of all define a common language to talk about the entire solutions in a standard, shared way;
– patterns intent: patterns are always motivated by an explicit intent; this intent is the real high-level need of the developer, whereas the solution that uses classes, methods overriding, methods delegation, methods callbacks… is nothing but the best known way to meet the intent using OO language.

UML support for patterns is quite minimal (dash lined and named bubbles with links to every participant in the pattern), and adds nearly no value compared to simple UML comments. If you know the patterns, and you do if you’re reading this to this line, I’d better tell you “this package contains adapters from the third party financial instruments tree to our custom financial instruments tree” than show you a diagram with 35 classes in a package and 35 classes in another package, 35 interfaces and 35 bubbles showing the pattern Adapter is applied 35 times respectively for each class, class and interface…

In the business design (some say analysis), the same is true. It’s shorter and more accurate to say the model follows the Contract pattern (Fowler), than to show the UML diagram. But on the other side, there is no formal language, visual or textual, other than plain English to describe patterns at their full level. At this level, packages would would be first-class entities, not just boxes that contains classes. Code generation could also go one step further, since if the machine knows about our intent, it could also provide the solution to our intent, maybe by implementing the correct pattern automatically, using the best implementation tradeoff automatically, but now I’m dreaming…

Initially published on Jroller on Tuesday March 15, 2005

Read More