Internalise the criteria
Examples of the solutions in design patterns are found in source code for some
languages but in features for others.
First criterion – They are real
It’s only a pattern if you can give an example. This first criterion should be obvious, but some examples from the published works disagree. So, I shall start with this and claim that examples prove a pattern can be enacted. They provide a starting point for a mental image. Examples allow a pattern description to explain extension or adjustment to match different contexts.
Christopher Alexander claimed, ‘If you can’t draw a diagram of it, it isn’t a pattern’[TTWoB79]. I believe code design patterns need source code, and management patterns need anecdotes, because all patterns need a few structured examples. Buildings need diagrams because they present forms. Code patterns need source code because they illustrate relationships of code forms. Management patterns need anecdotes because they represent timelines of people’s lives. The examples should not only be from where the pattern was applied correctly but also from where they were misapplied or absent. When we learn to use patterns, we learn how to repair things.
Look for evidence that patterns are true and real, but also look for evidence that they are
false. Examples such as
Second criterion – A process and a thing
So, the second criterion for a pattern is a clear description of a state of stress or disrepair. A diagram or code example will help, or a story about the pain can set the scene. The reason why the pattern is applied must be apparent, not just what the solution looks like.
Many so-called design patterns are just wrapped-up solutions. They either don’t
help at the root or are not necessary. For example,
Another problem with
When a method on the target can return a
A pattern interacts with other patterns. The way
Third criterion – They are wholesome
Beware of unfinished patterns. Refine them and seek out all the edges. If you don’t, you risk stating there is no solution where one exists. The third criterion is that a pattern stands alone but is related to other patterns.
Reading a file line by line is a pattern repeatedly observed since UNIX’s first years. Formatting strings in printing functions, finite state machines, handing out agents or handles to users of APIs rather than raw memory access, and cursors for query languages are all patterns that we see in programming but that are missing from the GoF book[GoF94]. The criterion for a pattern there seems to be the repeated finding of an object-oriented alternative to an existing solution outside the object-oriented space.
Fourth criterion – They address problems of design
There are non-object-oriented ways to express most of the GoF book patterns. GoF patterns that can be reinterpreted in this way could be considered idioms of an object-oriented design approach to the problem they address. The fourth criterion is that patterns are problem-centric. A pattern or pattern language is not paradigm-specific. It must be centred around solving a problem, not just offering an alternative solution using different tools.
Fifth criterion – They are responsive
The fifth criterion is related to emergence. When people latched onto the idea of patterns, they failed to attribute enough importance to the concept of forces. They understood the context part well, so they made that the way to identify where a pattern fits. If the context is correct but the forces don’t match, it’s not a pattern. It can still be a solution or simply something to be expected. Patterns generate solutions. Forces often generate patterns. If a recurring pattern cannot be found at the centre of a given set of forces, it’s more likely someone’s attempt at a pattern.
For example, I am a primitive human living in the jungle. I know how to make and use string and create tools from raw materials. This is my context. I have access to wood, flint, vines, and other resources. These are also part of my context. There are animals all around the forest. Some fly, some climb, and some move around at ground level. These are all part of the context. This context does not elicit any patterns, as there are no forces. It’s a stage upon which forces will play, but it does not suggest anything independently without first identifying the forces at play.
The forces I add to the system are: I am a hungry human who can scrounge for nuts and berries, but they are not plentiful at ground level. I am big and clever, but I cannot catch the small, weak animals at ground level, as they are too fast, and I need help to reach the ones that climb or fly.
We can see how a few patterns emerged once I added forces to this context. We will make tools to create ways to reach the fruit or animals beyond our reach, set traps for the skittish animals eluding our grasp, or even invent the bow and arrow. These are patterns because they are recurring solutions that resolve forces in a context. They have objective criteria of both context and forces.
Forces are the value of success and the cost of failure for each contextual relationship. The animals want to survive, so they will flee humans as they approach, but we need to get close to catch them so extend ourselves by trap or ranged weapon to resolve the conflicting forces. To get at the fruit higher up, because humans cannot reach that high and free climbing comes with greater and greater risk the higher we climb, we build ladders or climbing gear to reach great heights more safely, resolving those conflicting forces.
It’s the unresolved forces that drive the appearance of patterns. This is the last criterion.
- They are real: there are real examples.
- They are a process and a thing: the state of distress is well described. They repair and make things better.
- They are wholesome: they are both fully contained and related to other patterns. They support, not inhibit, the resolution of neighbouring problems.
- They address problems of design: a pattern or pattern language is not paradigm-specific and not an implementation.
- They are responsive: patterns must be emergent from the unresolved forces and resolve them.
The memento iterator pattern in the GoF book is quite a stretch and is almost an anti-pattern as it splits lifetime responsibility between two separate objects, hence my discounting it.