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 A Pattern Language[APL77]. It’s a real shame we misunderstood this aspect of cataloguing.

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: Doorway

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 Doorway. It takes the concept of a wall but makes it an active and separate entity that provides safe passage without damaging the wall into which it is embedded. This dynamic wall (from hereon called the Doorway) is a compound solution made of two parts, the frame and the door, and moves on hinges or runners. In some circumstances, you may not even need the Door element of the Doorway and simply use the frame to create a portal between rooms. The pattern of Doorway is not limited to static buildings. We see uses for the Doorway pattern on cars and trains, as well as on less solidly built structures such as tents and fields for cattle, despite those walls being less expensive to repair.

Some Doorway implementations will lead to the outside and the public world, while others will bridge the gap between internal rooms. The Door element in a Doorway to the outside may need to be:

  • 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 Door needs to survive the environment or whether the Doorway should keep the weather from passing through and into the structure’s interior.

The material for a Door depends on its final use, so be sure to determine the strength, weight, fireproofing, and waterproofing requirements before settling on a design. Any Door on a boat or submarine has critical constraints in this regard. Other necessary material properties, such as transparency or flexibility, may also apply. An inflexible Door to a field or garden may become brittle or warped and unsuitable for use because it no longer locks effectively. The Door on a greenhouse or a shower should be transparent in most cases. A Door leading to a beautiful outdoor place, such as a garden, should at least be partially made of transparent material; however, you may wish to choose a soundproof material if your children are loud.

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 Doors made of glass.

Mixed levels of security within a single Door exist. For example, you might like some things to pass through the Door without requiring permission, while others need the owner to unlock the Door. Examples include your mail or postal deliveries, which use letterboxes, or cats, which often don’t. You may also want to consider that even though you might not want someone to see through a Door, you may wish for light or air to pass through, so you can introduce a little window above the Doorway or just have the Door not sit snugly inside the Doorway, such as in restroom cubicles. Fitting letterboxes or cat-flaps to restroom Doors is not recommended.

In conclusion, the pattern of Doorway invites us to introduce a permanent hole into a wall when we seek a way to get from one room to another. We either frame it in such a way that you can tell it was not a construction accident or include a Door with or without a lock, made of a material appropriate for the level of privacy and security.

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 224 LOW DOORWAY and 237 SOLID DOORS WITH GLASS, it’s the lowness or light transfer that is essential, not the door. Otherwise, there would only be one pattern, indicating only one problem.

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 Doorway pattern add up to too much to look at. No wonder people can’t figure out what to do with patterns that include these highly detailed descriptions. When building a door for a car, why would you even consider a cat flap? Why would you wonder about whether it needs to be fireproof? There’s too much going on in this description, and yet, it’s also too terse. It’s too much and not enough at the same time. This is because Doorway isn’t authored in a way that benefits people.

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 Doorway pattern, with all the possibilities, you end up suffering the same problem you have in overly generic code. Because you don’t have any basic assumptions, there will be too many contexts to find out what could be a nearby related problem. In software, this is especially true where things are so similar that you’ll find that almost every pattern is related to every other pattern until you start whittling down the number of contexts.

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 Doorway pattern.

  • 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, A Pattern Language, have charming names describing what they are about and what they reinforce or create. 159 Light on two sides of every room is wholesome and reinforces the importance of diffuse light without ever literally demanding windows. But these names result in a quandary for those hunting down solutions to their problems. You can’t find them by these names. They’re lovely patterns, but it is necessary to read them to understand their value And you often only know their relevance after you have read them. Who would think that 159 Light on two sides of every room had any application to lighting an emotional scene in a film?

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.

1

e.g. The Caterpillar’s Fate. What, you can’t immediately guess this is a pattern for the transformation process from analysis to design?