Comments on Design Patterns
Design Patterns: Elements of Reusable Object-Oriented Software, by
Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, distills a
number of useful tools for crafting designs. However, not all of these
patterns are created equal. Here's my summary, in subjective order:
- Composite
- Parts and wholes conform to the same interface.
- Adapter
- An intermediary which changes the interface of an object.
- Iterator
- Stylized kind of adapter.
- Decorator
- An intermediary which attaches behavior to, but does not change
the interface of, an object.
- Proxy
- Stub which bridges to another machine or device. Aka "virtual object."
- Strategy
- Delegation for changing behavior. Generalizes higher-order functions.
- Bridge
- A stylized kind of Strategy pattern.
- State
- Encapsulate state-dependent behavior into separate objects.
Switch-style forwarding.
- Template method
- A framework. "Don't call us, we'll call you." Combination of
facade and strategy.
- Facade
- Stylizes the use of other classes, without adding functionality.
Aka "convenience routines."
- Mediator
- Reduces the number of interconnections between senders and
candidate recievers. Can do other things besides forward messages.
- Chain of responsibility
- Mediator which only forwards messages. Aka "merge."
- Observer
- Maintain a list of dependents to notify of changes. Part of MVC.
- Flyweight
- Omit state from an object's representation, to promote sharing.
State is not stored but rather passed as a method argument.
- Memento
- Opaque object for holding state. Can be used for iteration.
- Interpreter
- Stylized kind of visitor. Distributes an operation over a
hierarchy of composite patterns.
It is interesting to note that several other organizations of these
patterns have been proposed, by various people, all of which seem to
associate different things with each pattern. It is still an open question
what organization designing minds use.
C++
The book does a great job of pointing out pitfalls in C++, e.g.
-
the combination of interface and implementation inheritance
-
the use of inheritance instead of delegation or forwarding
-
the safety/flexibility tradeoff
-
the confusion between lexical and dynamic scoping in methods
-
the flat class namespace.
In fact, some of the patterns appear to exist simply because of C++'s
limitations:
- Abstract factory
- A class parameterized by another class, sort of. An artifact of
classes not being values in C++.
- Factory method
- A method parameterized by another class, sort of. Same explanation.
- Singleton
- Aka "oddball." An artifact of the object/class distinction in C++.
- Prototype
- Structured instantiation. Could use a closure instead, but C++ doesn't
support them.
- Command
- A callback object. Can return a command which undoes this one.
Could replace with a closure, if only one
Exec()
method
is needed.
- Visitor
- Add new operations to classes without changing them. An artifact
of multi-methods being missing from C++.
Comparisons
SICP has far more patterns and more complex
patterns, but doesn't distill and analyze them the way Design
Patterns does.
The Beta language manual is also a good source of patterns.
Thomas Minka
Last modified: Mon Jan 6 14:08:16 EST 1997