Today, let's take a closer look at design patterns.
What is a pattern?
The author quotes Christopher Alexander, an architect whose books A Timeless Way of Building and A Pattern Language have inspired the software pattern movement:
Each pattern is a three-part rule, which expresses a relation between a context, a problem and a solution.Software patterns appear as part of catalogs of individual patterns, and should not be viewed as stand-alone prescriptions, but rather in conjunction with other, alternative patterns.
As an element in the world, each pattern is a relationship between a certain context, a certain system of forces which occurs repeatedly in that context, and a certain spatial configuration which allows these forces to resolve themselves.
As an element of language, a pattern is an instruction, which shows how this spatial configuration can be used, over and over again, to resolve the given system of forces, wherever the context makes it relevant.
The pattern is, in short, at the same time a thing, which happens in the world, and the rule which tells us how to create that thing, and when we must create it. It is both a process and a thing; both a description of a thing which is alive, and a description of the process which will generate that thing.
Patterns Happy
"Patterns-happy" programmers tend to overuse patterns. They are so much in love with patterns that they apply them regardless of whether their use is justified, making code unnecessarily complex instead of simplifying it. They simply must use patterns in their code.
When learning patterns it is hard to avoid being patterns-happy. The true joy of patterns comes from using them wisely. Refactoring helps us to that by focusing our attention on removing duplication, simplifying code and making code communicate its intention. Evolving systems through refactoring makes over-engineering with patterns less likely.
There Are Many Ways to Implement a Pattern
The famous book Design Patterns by Erich Gamma et al begins the discussion of each pattern with a structure diagram. It is important to realize that this structure diagram is just an example and that there are multiple implementations of the pattern possible, depending on the need at hand. Alternative implementations are often discussed in the implementation notes. But all too often a programmer looks at the diagram and begins coding, assuming that the diagram is the way to implement the pattern.
Deviating from the standard implementation is inevitable and in fact desirable.
The evolutionary approach to software design often leads to minimalistic pattern implementations, which are simpler than classical pattern definitions, because they involve implementing only what is necessary. This is the approach used throughout this book.
Refactoring to, towards and away from Patterns
Depending on the nature of a pattern, one can refactor to the pattern, towards it and even away from it. For some patterns, like Composed Method or Template Method, one has to refactor all the way to the pattern, it does not make sense to refactor half way towards it. For other patterns, it is sometimes sufficient to improve the design by refactoring towards them even if you do not go all the way.
If after the refactoring to a pattern, you feel that your design has not improved enough, you can decide to refactor away from this pattern to another pattern.
The goal is to obtain a better design, not to implement patterns!
On the other hand, some patterns implementation can make code unnecessarily more complex; in that case, backtracking or more refactoring is needed.
Knowing patterns is not enough to evolve great software, you must also know how to intelligently use patterns. Yet, if you don't study patterns, you'll lack access to important, even beautiful, design ideas.
A good way to learn patterns is to choose great pattern books to study and then study one pattern a week in a study group. Meeting and discussing important design ideas each week is a great way to become better software designers.
Advice: only read the great books!
If after the refactoring to a pattern, you feel that your design has not improved enough, you can decide to refactor away from this pattern to another pattern.
The goal is to obtain a better design, not to implement patterns!
Do Patterns Make Code More Complex?
In general, pattern implementations ought to remove duplicate code, simplify logic, better communicate intention, and increase flexibility. Yet, people's familiarity with patterns plays a major role in how they perceive refactoring to patterns. It's better that team learn patterns rather than avoid using them, because the teams view patterns as being to complex.On the other hand, some patterns implementation can make code unnecessarily more complex; in that case, backtracking or more refactoring is needed.
Pattern Knowledge
Patterns capture wisdom. Reusing that wisdom is extremely useful.Knowing patterns is not enough to evolve great software, you must also know how to intelligently use patterns. Yet, if you don't study patterns, you'll lack access to important, even beautiful, design ideas.
A good way to learn patterns is to choose great pattern books to study and then study one pattern a week in a study group. Meeting and discussing important design ideas each week is a great way to become better software designers.
Advice: only read the great books!
Up-Front Design With Patterns
The author prefers to evolve a system, refactoring to, towards or away from patterns as necessary. Up-front design with patterns has some place in a designer's toolkit, but use it rarely and most judiciously.