There Are Many Ways to Implement a Pattern
Every pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice. [Alexander, PL, x]
Every pattern in the classic book Design Patterns [DP] contains a Structure diagram. For example, the Structure diagram for the Factory Method pattern looks like this:
This diagram indicates that the Creator and Product classes are abstract, while the ConcreteCreator and ConcreteProduct classes are concrete. Is this the only way to implement the Factory Method pattern? By no means!
In fact, the authors of Design Patterns go to great pains to explain different ways to implement each pattern in a section called Implementation Notes. If you read the implementation notes for the Factory Method pattern, you'll find that there are plenty of ways to implement a Factory Method. For example, the following diagram shows another way:
In this case, the Product class is abstract, while every other class is concrete. In addition, the Creator class implements its own factoryMethod(), which the ConcreteCreator overrides.
There are even more ways to implement the Factory Method pattern. Here's another one:
In this case, the Product class is concrete and has no subclass. The Creator, which is abstract, defines an abstract version of the Factory Method, which the ConcreteCreator implements to return an instance of Product.
The main point? There are many ways to implement a pattern.
Unfortunately, when programmers look at the solitary Structure diagram accompanying each pattern in the Design Patterns book, they often jump to the conclusion that the Structure diagram is the way to implement the pattern. If they'd only read the crucial implementation notes, they'd know better. Yet many a programmer picks up Design Patterns, gazes at a Structure diagram, and then begins coding. The result is code that exactly mirrors the Structure diagram, instead of a pattern implementation that best matches the need at hand.
A few years after the publication of Design Patterns, John Vlissides, one of the book's coauthors, wrote:
It seems you can't overemphasize that a pattern's Structure diagram is just an example, not a specification. It portrays the implementation we see most often. As such the Structure diagram will probably have a lot in common with your own implementation, but differences are inevitable and actually desirable. At the very least you will rename the participants as appropriate for your domain. Vary the implementation trade-offs, and your implementation might start looking a lot different from the Structure diagram. [Vlissides]
In this book, you'll find pattern implementations that look quite different from their Structure diagrams in Design Patterns. For example, here's the Structure diagram for the Composite pattern:
And here is a particular implementation of the Composite pattern:
As you can see, this implementation of Composite bears little resemblance to the Structure diagram for Composite. It is a minimalistic Composite implementation that resulted from coding only what was necessary.
Being minimalistic in your pattern implementations is part of the practice of evolutionary design. In many cases, a non-patterns-based implementation may need to evolve to include a pattern. In that case, you can refactor the design to a simple pattern implementation. I use this approach throughout this book.