Unfindable
When hunting down a pattern to use, you will not locate a well-defined or widely recognised index to them all. Many are poorly named or hidden inside another language behind a further layer of contexts.
Naming patterns is tricky. Some of them have names that seem utterly unrelated
to their purpose1. However, knowing which one you are looking for
is difficult, even when the name perfectly captures its essence. Because we named
software design patterns after their solution form, they dislocate patterns that are
united by a common cause but join those solving tenuously connected problems.
This is how most software patterns have been catalogued, so the problem
surfaces in most examples. It’s even true for a handful of the patterns in
To understand what it means when I claim design patterns are typically presented using the wrong aspect, it’s worth considering a made-up pattern related to real-life architecture and buildings. I will show how something—when described as a pattern from a solution rather than a problem perspective—becomes an unwieldy mess. I aim to align with the style of the most famous software design patterns and show how it misses the mark. For this exercise, I will take an elementary example—a pattern for passing through a wall.
Who would say the pattern of a door was not a design pattern? It’s a structured solution to a recurring problem, used repeatedly. So surely it is a pattern, right?
Fake pattern:
You very often find the rooms of a house, or even the house itself, quite difficult to use if there are no entrances. People have been known to use windows to gain entry, but those people are often not the intended users of the house at all. For the people who own the house, a mechanism by which they may enter without causing damage to the walls would benefit them and the house alike.
This way of passing through a wall is called a
Some
- Resistant to weather
- Resistant to attack
- Secured against prying eyes
- Resilient to accidental damage incurred by collisions with other vehicles
- Have low wind resistance when used to separate open spaces such as fields
The level of weather resistance must accord with whether the
The material for a
Rooms have a range of privacy requirements, and some must be secure, so
introduce a locking mechanism. However, the lock may need to be disabled from
one side all the time, such as when it’s an escape route. Frequently, the lock
need not be keyed; a simple bolt or latch will suffice. The level of complexity
in a lock usually indicates the necessary level of privacy, which often
correlates with the strength and opacity of the materials used. However, there
are some tiny, smelly rooms where a simple bolt lock or latch is sufficient,
but they don’t suit
Mixed levels of security within a single
In conclusion, the pattern of
Hopefully, you at least found this funny, but do you see how it’s a description of doorways, and yet it’s not a pattern? Poor patterns often read like descriptions of the obvious. However, they carry lots of extra details to give it fullness. Here, we talk about doors and their many incarnations, but we don’t align motivation with resolution or consider the consequences for people’s lives. We never got any insight into why and when you would choose each type of variation.
When you look at the original work by Christopher Alexander, you won’t find the
pattern of a door. Instead, you will find many patterns that include a door or
a doorway as a required element for completion. The door may be described in
those patterns, but it’s never the centre of the pattern.
Even in the patterns
Some characteristics may be brought to attention, and some warnings may be laid out about decisions you might make, but there is no pattern of doors in general. Doors are components of patterns. They are the materials or elements of a configuration. Patterns are definitely not just better names for features; if they name anything, they name configurations.
All these details in the
Patterns are the identifiable steps you apply to solve the problem of how to build a thing, not the thing itself. This has been a constant problem. What they are is distinct from what you might look for. You look for an unknown but specific solution to a real problem you have but cannot fully describe. You want solutions to complications arising from situations, including information about what else to measure, verify, and evaluate. That’s where the benefit lies in pattern languages. They link together many patterns and expose problems previously unknown to their readers.
Looking for things by pattern names was always going to require more luck and effort than looking for them by context. It’s why we should never have based pattern names on their solutions. If we had identified them by the pain caused by the problem or easily perceivable elements of the problem, I might not have had a story to tell.
When you set out your patterns like the
Consider a pattern of a stack. If you try to handle all the options, you will
overwhelm the person trying to define it. You might have one particular stack
in mind, so I will list a few so that you can imagine the breadth of content if you
were to attempt to describe it in the manner of the
- An array and a
head
variable - C++ stack container based on the
std::deque
class - A linked list-based stack of objects
- A stack with varying sized elements, such as is used by the runtime in C and other stack-based languages
- An auxiliary structure to provide a stack-like interface to pre-existing objects
Documentation for a simple problem like this will explode in complexity for the reader if we fail to differentiate between the kind of stack used at the low level and the kind used at the language level. A lack of context or too many contexts diminishes the value of design patterns.
It’s easy to accidentally start adding corner cases, as options and flexibility are like catnip to programmers. Many otherwise compelling books on design patterns have made this mistake. Indeed, some solutions have many different possible uses. But because of this, when someone begins to document them as a pattern, they strive to find a generic form. Then, the resultant treatment fails to capture the value of each unique situation.
As a takeaway, think about patterns from their problem context alone, not from the point of view of what you should call a pattern solution or what other patterns are similar or related in how we categorise them. Naming patterns is only a worthwhile practice for conversations about pattern selection for a larger design. It would be preferable to name them by context alone, but those names are lengthy and complicated.
If we take the problem as the starting point, things improve. For most GoF book patterns, the problem was often related to coupling or lack of variability. That’s only two apparent patterns. The second is dealt with by nominalisation—the extraction of variability into an object. We could rewrite the GoF book into just three or four patterns, with many examples of how to use those patterns to provide solutions in different contexts.
This naming fault even exists in the works of Christopher Alexander. Some
patterns in the original pattern book,
Context is a better basis for finding patterns when considering how we look for things when needed. You may wish to look for a real solution to a concrete problem you have right now. In this case, you can only use patterns if you already understand them or understand enough of them to know where to look. Finding the fix for your problem can be taxing if you’re unaware of the pattern that fits. What you have is information about the problem rather than the solution.
As a counterexample, when it comes to sorting algorithms, you know when you need one and where to look for it. You realise you need to regularly find something in your container based on some ordering of the set, or the items must be sorted for processing by a method outside your control. You are aware of your problem, and you know the type of solution to look for. You can do a web search for sorting algorithms, learn about the big O notation if you haven’t already, and then select an appropriate solution based on your expected data. You can either happily implement it yourself or use a library to solve your problem without doubting that the solution suits the job.
Sorting is a pattern, but we know it. We know the name but might not know the correct solution form, so we look up the pattern information (big O, time/space trade-offs, stability) and select a solution resolving our specific forces in the context of needing to sort.
Sorting is one of the many foundational subjects of programming literacy. When I was a child, I worked on a program on a ZXSpectrum in BASIC, and not knowing about route planning algorithms caused me to reach an impasse with my little game project. Lacking even the knowledge of what I was looking for stopped me from finding a solution. I didn’t know I needed a path-finding algorithm to solve my problem. I only knew I didn’t know which way the enemy robots should step to move towards me when I added obstacles to the world. Patterns are analogous to this. When you cannot clearly articulate your problem, finding the pattern to solve it is virtually impossible. We teach a broad range of algorithms in programming courses so you know the categories of problems you could face. You use them as a lexicon in your search for solutions.
Another time we don’t need to know the pattern names is when someone else does. Names worked out fine for Christopher Alexander because the way they worked included a phase in which they built up a smaller language to match the project they were working on. His team found the necessary patterns and presented just these few to the people involved in the process, just like Kent Beck and Ward Cunningham did for those novice developers in 1987[UPL87]. So, we need to add knowledge of patterns at an architectural and leadership level. The architect or lead can use patterns to help guide others to a better solution. However, this isn’t possible because of a problem: unavailability.
e.g. The Caterpillar’s Fate. What, you can’t immediately guess this is a pattern for the transformation process from analysis to design?