153

Ever since I first learned about the Gang of Four (GoF) design patterns, at least 10 years ago, I am having the impression that these 23 patterns should be only a small sample of something much larger which I like to call the Pattern Space. This hypothetical Pattern Space consists of all recommendable solutions (known or unknown) for common object oriented software design problems.

So I expected the number of known and documented design patterns to grow significantly.

It did not happen. More than 20 years after the GoF book came out, only 12 additional patterns are listed in the Wikipedia article, most of which are much less popular than the original ones. (I did not include the concurrency patterns here because they cover a specific topic.)

What are the reasons?

  • Is the GoF set of patterns actually more comprehensive than I think?

  • Did the interest in finding new patterns drop, maybe because they have been found to not be all that useful in software design?

  • Something else?

10
  • 50
    Patterns are everywhere but they're often used in a tasteless and robotic way. For that reason, I think, the pattern catalogue idea became less popular.
    – usr
    Commented Nov 12, 2016 at 22:04
  • 7
    Design space? Someone get Mark Rosewater down here, stat!
    – corsiKa
    Commented Nov 13, 2016 at 8:05
  • 17
    Martin Fowler published Patterns of Enterprise Application Architecture in 2003 documenting about 50 patterns, many of which are still quite reconizable and well-used today, e.g. "Data Mapper", "Plugin", "Lazy Load", "Service Layer", etc. Commented Nov 13, 2016 at 18:17
  • 2
    Exploring the space of all possible patterns would be like not exploring the space of possible patterns at all. You can make everything a pattern. If you make everything a pattern then nothing is a pattern, as the word loses it's meaning. Commented Nov 14, 2016 at 13:07
  • 4
    @BradThomas: Sure, like with most interesting questions, people tend to have a certain opinion. But opinions are at least partly based on facts, and I have found many intersesting facts in the answers to this question that will help myself and hopefully others to re-think their opinions and come to more substantiated ones. Commented Nov 15, 2016 at 7:46

14 Answers 14

172

When the Book came out, a lot of people thought that way, and there were many efforts to create "pattern libraries" or even "pattern communities." You can still find some of them:

But then...

Did the interest in finding new patterns drop, maybe because they are not really that useful in software design?

This, very much. The point of design patterns is improve communication between developers, but if you try to add more patterns you quickly get to the point where people can't remember them, or misremember them, or disagree on what exactly they should look like, and communication is not, in fact, improved. That already happens a lot with the GoF patterns.

Personally, I'd go even further: Software design, especially good software design, is far too varied to be meaningfully captured in patterns, especially in the small number of patterns people can actually remember – and they’re far too abstract for people to really remember more than a handful. So they’re not helping much.

And far too many people become enamoured with the concept and try to apply patterns everywhere – usually, in the resulting code you can’t find the actual design between all the (completely meaningless) Singletons and Abstract Factories.

23
  • 50
    Controversial opinion: The abstract factory is a code smell anyway :)
    – MetaFight
    Commented Nov 12, 2016 at 16:20
  • 66
    Controversial opinion, maybe, but an oh so important opinion to express. Design patterns are in danger of becoming an example of the emperor's new clothes, where we are all scared to question whether they are useful. Well done.
    – David Arno
    Commented Nov 12, 2016 at 19:39
  • 20
    @MetaFight ControversialDesignPatternOnlineOpinionHumanReadableRetortFactory.newInstance().getText();
    – corsiKa
    Commented Nov 13, 2016 at 8:08
  • 11
    "The point of design patterns is improve communication between developers" I thought design patterns were to solve problems that were commonly (and quite often independently) encountered by developers. Standards improve communication, and due to fluctuations (patterns arising from XY problems, patterns being considered anti-patterns) many don't consider design patterns to be standards. Design patterns are good at pin-pointing lack of language features, and I believe language designers are implementing these problem-fixes before they become design patterns. Don't take my word for fact though
    – Dioxin
    Commented Nov 13, 2016 at 20:19
  • 11
    @ChrisW I don't see your point... As I said the GoF tried to overcome OO shortcomings, and especially C++98 shortcomings as this was their language of choice along with Smalltalk. They actually wrote : "The choice of programming language is important because it influences one's point of view. Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily."
    – Shautieh
    Commented Nov 14, 2016 at 3:36
111

I am having the impression that these 23 patterns should be only a small sample of something much larger which I like to call the Pattern Space.

This is the dreadful assumption that is propagated by neophyte programmers everywhere, programmers who think that they can write a program merely by stitching together software patterns. It doesn't work that way. If there is such a "pattern space," you can assume that its size is effectively infinite.

Design patterns (in the GoF sense) have but one purpose: to compensate for deficiencies in the programming language you are using.

Design patterns are neither universal nor comprehensive. If you change to a different, more expressive programming language, most of the patterns in the GoF book become both unnecessary and undesirable.

31
  • 41
    "Design patterns (in the GoF sense) have but one purpose: to compensate for deficiencies in the programming language you are using." I keep hearing this, but have yet to see it justified. Every supposed justification of it just points to a handful of patterns that are easier to implement in languages with some feature -- usually Visitor and perhaps Singleton -- and leaves the vast majority of patterns untouched, just implying that they too can be made redundant by better languages. But how do we know? What language feature makes Observer irrelevant? Chain of Responsibility? Composite?
    – Jules
    Commented Nov 12, 2016 at 19:54
  • 59
    @Jules First class functions alone eliminate a sizable chunk of them, including Chain of Responsibility (it's just composition of a list of functions). Functional reactive programming eliminates the Observer pattern. The Composite pattern is just a less-rigorously specified definition of monoids, and languages with typeclasses and a focus on algebraic laws give powerful tools for working with monoids. I could list plenty more but you get the idea.
    – Jack
    Commented Nov 13, 2016 at 0:10
  • 14
    @Jules: I believe the original GoF book listed iterator as a pattern, but now its transformation into language feature is basically complete in every remotely OOP language.
    – Kevin
    Commented Nov 13, 2016 at 5:25
  • 10
    @RubberDuck how is having the pattern already implemented making the pattern obsolete? It's still the design pattern being implemented. Different sets of language features might lead to different implementations of the pattern, but the pattern itself is still there. Patterns are there to ease communication by giving names to reoccurring strategies that's commonly used. Point in case, the .NET classes are called ObservableSomething<T> which makes it easy to understand their purpose, because it uses the commonly known pattern name. A pattern is an idea, not an exact implementation.
    – null
    Commented Nov 13, 2016 at 12:06
  • 33
    @Jules: What is a Program? A solution to a re-occuring problem. What is a Design Pattern? A solution to a re-occuring problem. Why is it not a program? Because we can't express it as a program. Ergo, a Design Pattern is a solution to a re-occuring problem that should rather be a Program, not a Design Pattern, but can't be a Program, because the language is not expressive enough to express the Program. Example: not too long ago, "Subroutine Call" was a Design Pattern! Nowadays, it is a language feature. Commented Nov 14, 2016 at 8:04
65

I think there are three factors that come into play here.

Lack of Critical Mass

First, a pattern is basically little more than giving a name to some code that implements a particular "chunk" of functionality. The only way that name provides much real value is if you can depend on everybody knowing what the name means so just by using the name, they immediately understand quite a lot about the code.

Patterns never established the critical mass they needed to accomplish that though. Rather the opposite, AAMOF. In the 20 (or so) years since the GoF book came out, I'm pretty sure I haven't seen as many as a dozen conversations in which everybody involved really knew enough design patterns for their use to improve communication.

To put it slightly more quaintly: design patterns failed specifically because they failed.

Too Many Patterns

I think the second major factor is that, if anything, they initially named too many patterns. In a fair number of cases, the differences between patterns are sufficiently subtle that it's next to impossible to say with real certainty whether a particular class fits one pattern or another (or maybe both--or perhaps neither).

The intent was that you'd be able to talk about code at a higher level. You'd be able to label a fairly large chunk of code as the implementation of a particular pattern. Simply by using that pre-defined name, everybody listening would usually know as much as they cared about that code, so you could move onto the next thing.

The reality tends to be nearly the opposite. Let's say you're in a meeting and tell them that this particular class is an Facade. Half the people in the meeting either never knew or have long since forgotten exactly what that means. One of them asks you to remind him of the exact difference(s) between a Facade and, say, a Proxy. Oh, and the couple of people who really do know patterns spend the rest of the meeting debating whether this should really be considered a Facade or "just" an Adapter (with that one guy still insisting that it seems like a Proxy to him).

Given that your intent was really just to say: "this code isn't very interesting; let's move on", trying to use the name of a pattern only added distraction, not value.

Lack of Interest

Most design patterns don't really deal with the interesting parts of code. They deal with things like: "how do I create these objects?", and "how do I get this object to talk to that one?" Memorizing pattern names for these (as well as the aforementioned arguments over details and such) is simply putting a lot of energy into things most programmers just don't care very much about.

To put it slightly differently: patterns deal with the things that are the same between lots of programs--but what really makes a program interesting is how it's different from other programs.

Summary

Design patterns failed because:

  1. They failed to achieve critical mass.
  2. Differentiation between patterns was insufficient to guarantee clarity.
  3. They mostly dealt with parts of code almost nobody really cared about anyway.
7
  • 2
    "...but what really makes a program interesting is how it's different from other programs." I completely agree but for that you have to first get the same part right, maybe they just differ by some trivial aspect. If you relax a bit the need to name and identify patterns I'm convinced one sees patterns almost everyhwere. It's just that they do almost never come in their pure form but are always more or less adapted to the problem at hand. Commented Nov 14, 2016 at 11:55
  • 5
    Very good answer. Commented Nov 14, 2016 at 16:01
  • 4
    @Trilarion: Oh, I realize those parts of the code have to be written. They're a little like, say, the tires on your car. You pretty much need tires to drive at all--but most people still barely know the brand of tires on their car. This is asking that they learn special terminology for a tire with asymmetric diagonal grooves. Who knows--those might have saved my life once, but I still don't spend my life learning names for them. Commented Nov 14, 2016 at 22:04
  • 3
    @DavidRicherby: Okay, then let's use a "producer side" version of the analogy. Does it matter that John who designs tires for Goodyear uses one word for that type of groove, but Pierre who works for Michelin uses an entirely different word? Does it matter that one uses a word referring only to the groove, but the other a word referring to a complete tire with horizontal grooves on one side of the center and diagonal grooves on the other? Commented Nov 16, 2016 at 14:51
  • 2
    @immibis: I would say mostly yes, they've failed. I'd say there are fewer than half a dozen patterns most programmers recognize. Singleton is well known, but actually only rarely applicable (at best). The name "Factory" was in common use long before "patterns" came along (I remember its use in the late 1970's or very early 1980's). Patterns were supposed to form a vocabulary, but currently they're about like my vocabulary in Greek--enough to (possibly) get myself in trouble, but certainly not enough to order off a menu, much less hold a meaningful conversation. Commented Jan 10, 2018 at 1:17
36

Patterns are missing abstractions, simple patterns are abstracted, complex patterns are not recognized, so patterns are not useful (except a few high level ones).

I think Paul Graham said it best:

When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.

When you recognize a pattern in your code, it means something repeats itself and you should use a better abstraction. If you don't have a better abstraction, you use the pattern as a workaround. Because newer programming languages provide better abstractions, patterns become much less useful.
Also simple patterns are often easily abstracted and complex patterns rarely recognized.
When a pattern becomes replaced by an abstraction, it does not mean that the concept behind the pattern disappears, but that the concept can be written explicitly instead of indirect and that it is no longer special compared to other code and it becomes no longer recognizable as a pattern.

8
  • 2
    Personally, I somehow really like this idea. But then, code should be readable by humans and people like patterns. Patterns help us finding our way around. Removing all patterns from our code will make it unreadable. Commented Nov 13, 2016 at 11:58
  • 2
    @Frank I think where PG is coming from is that a pattern is a 'smell' of an underlying function that you can abstract, & the fact that you haven't pulled it out into a function or macro is what's causing the repetition ― like if you didn't have a String.replace function, you could imagine it popping up as a pattern, but better to write it once rather than continuing to reimplement it. Agree that if you don't name these things properly it would make it harder to read, but when it's done right, code reads more declaratively IMO (e.g. the getOrElse style of option monads vs null checking) Commented Nov 13, 2016 at 13:21
  • 12
    Paul Graham's quote was about keeping your solutions DRY, which is different from the GoF "pattern" idea. The GoF idea was about giving names to commonly used solutions. We already were doing that long before the GoF published their book. For example, I can tell my co-worker that I'm going to use a queue, and my co-worker immediately knows what I'm talking about without my having to explain the details of what a queue does or how it works. But, see Michael Borgwardt's excellent answer, above. Commented Nov 13, 2016 at 19:46
  • 10
    In my opinion, this answer misunderstands what patterns are. A design pattern is an often encountered solution to a common problem. It isn't some code duplication. Say, take an iterator. You solve the problem of abstracting away the container so you can go through the elements inside it regardless of what the container is. Thus you create an iterator class which does that for each of your containers and make them implement a common interface. What's to abstract here? An iterator already is an abstraction. And, of course, it's implemented differently for all containers, so no code duplication.
    – Malcolm
    Commented Nov 14, 2016 at 9:10
  • 3
    The key part of Graham's quote is often that I'm generating by hand the expansions of some macro that I need to write. This references Lisp macros specifically. There is only so much abstraction one can do without macros. Commented Nov 14, 2016 at 12:43
13

While I mostly agree with what others answered here, I personally think that a main reason for a not growing number of patterns is that patterns loose their meaning when there are countless ones. The nice thing with these few patterns is, that they cover a lot of problem domains in a standard way. If you'd focus on an endless pattern domain you'd end up with no pattern at all. It's a bit like "how long is the coast line of an island?". If you measure on a map you come with a decent number. But if you try to get more exact and got to a finer resolution, you will find that the length increases more and more to infinity (or uncertainty; how would you measure the exact border with tides and on atomic level?).

3
  • 1
    Right, patterns can only work if there are not too many of them. But why are the GoF ones still the most popular ones? Some of them are now considered as antipatterns by many people (Singleton, Builder, etc.). This should make room for new, more useful patterns without increasing the total number. Commented Nov 13, 2016 at 11:14
  • 3
    I guess it's like the 10 commandments. The source is only 2 chars away (GOF, GOE, GOD) xD
    – user188153
    Commented Nov 13, 2016 at 11:18
  • 9
    Yes, and it sometimes seems like modern software engineering relates to GoF like medieval scholastics relates to Aristotle. Commented Nov 13, 2016 at 11:30
12

Something that none of the other answers mention that is also relevant:

The rise of dynamically-typed languages.

When the book first came out there was serious discussion that Java was just too slow to do real work in. Now Java is frequently used over more expressive languages because of its speed. Maybe Ruby, Python, JavaScript, et al are still too slow for some important classes of applications, but by-and-large they're fast enough for most purposes. And JavaScript at least is actually getting faster despite having more features packed in every release.

The original GoF book had the patterns in both smalltalk and c++, and if memory serves the patterns were always shorter in smalltalk and sometimes significantly so. Some of the features of the classic design patterns are really ways to add dynamic features to a statically typed system (like the already discussed AbstractFactory, in which you instantiate the correct class based on runtime data). Others are so much shorter in dynamic languages that they simply meld into idiomatic use of the language itself.

11

It did happen. Dozens if not hundreds of books were published in what looked like an attempt to reduce the whole of computer science to design patterns, as publishers and authors attempted to jump on (or create) yet another bandwagon. I have a shelf of them. Never consulted since first scanned, and yes I was a sucker, because there was little or nothing in there of any actual use or that wasn't already well known (see for example Type Object, which is nothing more than third normal form expressed over a dozen pages instead of one paragraph), and because obviously the fewer patterns the better: a point which eluded most of the practicioners. Indeed, when I posted a rebuttal of Type Object, I was instructed to recast my text as a design pattern. True story. Which also shows another deficiency of the project: no review or exclusion or rejection mechanism.

As a matter of fact the GoF didn't actually attempt to 'thoroughly explore Design Patterns'. Rather, they were engaged on a much larger project: to introduce 'pattern language' into CS, with all its bizarre notational arcana of Forces, Participants, etc., which simply failed, because it was fundamentally misconceived, as well as being pointless.

What they did accomplish, which was useful, was two things:

  • publish several useful tricks such as the Visitor pattern
  • provide a standard set of names which has largely stuck: Factory, Adapter, Iterator, ... If you look at CORBA, which was designed immediately beforehand, you will see the value of this: all sorts of 'foreign' names such as Interceptor, Servant, Broker, ...

Another useful concept that arose was the 'anti-pattern', e.g. 'log and throw'. The project, like many fads in CS, was derailed by its own evangelism and by being misguidedly adopted as yet another CS religion, and it went the way of most such religions: useful in parts, but certainly 'no silver bullet' ((c) Fred Brooks, 1965). Sad that we have to keep rediscovering that every few years really.

3
  • Is it still sad if it resulted in this discussion (and all that entails)
    – r3wt
    Commented Jul 24, 2017 at 21:31
  • 1
    @r3wt Non sequitur. What I said is sad is the IT industry's weakness for thinking every new development is going be the mythical silver bullet, and incidentally for trashing some of its own prior work.
    – user207421
    Commented Jul 24, 2017 at 23:06
  • 2
    look at it from a different perspective. It's not sad for me reading your answer, learning not to repeat the mistake. so what you take for granted is actually very useful to others.
    – r3wt
    Commented Jul 25, 2017 at 0:43
6

There were/are several books titled PLoP (Pattern Languages of Program Design) which are each an anthology of papers presented at an annual conference.

Reading the books, I found some of the patterns were interesting and new to me, some of them standards (e.g. "half object plus protocol").

So no, the GoF's collection wasn't exhaustive, and inspired/inspires people to collect/describe/discover/invent new ones.

The "only 12 additional patterns listed in the Wikipedia article" presumably aren't a complete collection either: i.e. there are others documented elsewhere, e.g. in the PLoP books and maybe elsewhere too.

3
  • Yes, you can find descriptions of hundreds of patterns if you search for them. But none of these seems to be near as popular as the GoF ones. Commented Nov 13, 2016 at 10:54
  • It was because I liked reading the GoF book that I read more (books) when they were published (later).
    – ChrisW
    Commented Nov 13, 2016 at 11:07
  • 1
    @FrankPuffer I bet the patterns are popular, even if the names aren't.
    – dcorking
    Commented Nov 15, 2016 at 8:47
5

The Gang of Four (GoF) book contains most patterns that an experienced programmer in a none functional language have in their tool belt. It is like the basic set of tools that all builders know how to use. The primary contribution of the book was to give well defined name to the patterns that were in common use by most experienced programmers at the time and hence aid communication between programmers discussing design options.

You expect that an electrician to have some tools that a normal builder does not, likewise you would expect that a WPF programmer to know the design patterns for “Dependency Properties”, or a “SQL Programmer” to know the design pattern for using triggers to create audit data.

However we don’t think of these as “Design patterns” due to them only being used with one technology.

Some more modem design pattern books are “Refactoring, Improving the Design of Existing Code (Martin Fowler)” and “Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin)Both of these books present the contents as transformations you make to your current code, rather than as “pre canned reusable design”, however they are just as much “design patterns”.

5

Here is an interview with Erich Gamma where he reflect on their selection of patterns and what they'd change today (well today as of 10 years ago, haha).

http://www.informit.com/articles/article.aspx?p=1404056

Larry: How would you refactor "Design Patterns"?

Erich: We did this exercise in 2005. Here are some notes from our session. We have found that the object-oriented design principles and most of the patterns haven't changed since then. We wanted to change the categorization, add some new members and also drop some of the patterns. Most of the discussion was about changing the categorization and in particular which patterns to drop.

When discussing which patterns to drop, we found that we still love them all. (Not really—I'm in favor of dropping Singleton. Its use is almost always a design smell.)

So here are some of the changes:

  • Interpreter and Flyweight should be moved into a separate category that we referred to as "Other/Compound" since they really are different beasts than the other patterns. Factory Method would be generalized to Factory.
  • The categories are: Core, Creational, Peripheral and Other. The intent here is to emphasize the important patterns and to separate them from the less frequently used ones.
  • The new members are: Null Object, Type Object, Dependency Injection, and Extension Object/Interface (see "Extension Object" in Pattern Languages of Program Design 3, Addison- Wesley, 1997).
  • These were the categories:
    • Core: Composite, Strategy, State, Command, Iterator, Proxy, Template Method, Facade
    • Creational: Factory, Prototype, Builder, Dependency Injection
    • Peripheral: Abstract Factory, Visitor, Decorator, Mediator, Type Object, Null Object, Extension Object
    • Other: Flyweight, Interpreter
1
  • Why are you downvoting me? Please explain in a comment so I can improve the answer.
    – akuhn
    Commented Dec 23, 2016 at 19:07
3

The actual patterns in the book are sometimes really useful, but they are really just instances of a more powerful tool that the book gives you: a deep understanding of when and where it's better to cut monolithic code in independent parts separated and regulated by an interface.

When you learn that skill, you realize that you don't need to remember the exact details of every single pattern, as you can always cut the solution you are implementing in the way that best fits its purpose. So the idea of writing down more and more patterns seems very academic and pointless.

2
  • Good point, however I doubt that many people understand the book (or patterns in general) that way. Commented Jan 26, 2017 at 12:29
  • @lud1977 if we don't record history, what prevents the future from falling into the same traps? thus, it must always be recorded. its not pointless.
    – r3wt
    Commented Jul 24, 2017 at 21:35
2

So I expected the number of known and documented design patterns to grow significantly.

It did not happen. More than 20 years after the GoF book came out, only 12 additional patterns are listed in the Wikipedia article, most of which are much less popular than the original ones. (I did not include the concurrency patterns here because they cover a specific topic.)

The GoF book and Wikipedia are hardly the only source of known design patterns. If you just search for "design patterns" in Amazon.com you get hundreds of books (try this search). I guess they only list the most well known pattern in the Wikipedia article.

So the problem is not that there are not enough documented design patterns. Rather there are so many that nobody can memorize them all and most programmers recognize only a few. The big promise of common pattern language breaks down at this point.

0

There are probably plenty of structures that haven't yet been thought of. As long as people are developing software, there will be design challenges to overcome. Some of those may well be solved using clever new patterns that others could make use of.

Programming languages have developed and progressed to abstract away the most commonly used patterns. Those patterns still exist in the design of the languages. So they may be ignored today, but that doesn't make them unimportant.

Is the knowledge of how to construct a house suddenly unimportant once we have robots that can do it for us? I would argue no, it's not. It's less relevant, sure - and probably a lot less rewarding to study, since the demand did drop sharply, and no one else is studying it.

So no, I don't believe pattern space as you call it has been exhausted. As another answer pointed out, it's likely to be infinite. But as the demand for systems design dies down, as we increase the height of our tower of abstraction and the power of our programming languages - fewer and fewer people building away on the top tiers will pay attention to the details of how the tower was built.

-2

Patterns are infinite.. You can tweak each pattern or mix n match to create new ones.. Enterprise integration patterns are also well defined..so yes gof did take pain of documenting patterns using uml and created a standard for explaining them.. But for each domain patterns evolve and they also change for expressive language like python or scala..

Not the answer you're looking for? Browse other questions tagged or ask your own question.