When Books Could Code #1: Design Patterns
Posted on April 25, 2026
What is this?
I’ve spent my whole career fascinated by writing about programming. How do programmers explain what we are doing to each other? How have books written about programming changed the way we work and think? So now I’m writing about programming books.
If you think this is somewhat elegiac for the Era of the Programming Book, as the co-author of a 700 page programming book in an era where there will be roughly zero new 700 page programming books, yeah, kinda.
So this series, “When Books Could Code” (alluding, obviously, to the “If Books Could Kill” podcast, making my title the faint echo of somebody else’s joke, which somehow seems appropriate).
In the same way as the Ruby neighbor posts did, I’m going to try to give a sense of what the book felt like when it came out, how the book fits in to the world, what it changed and also what parts of it hold up or don’t hold up.
The Book
Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and Jon Vlissides, often referred to as “the Gang of Four”. Copyright 1994.
All the authors are listed on the back cover as “Dr.”, which is a bit of a key to what this book actually is. Per the book itself, it started as part of Erich Gamma’s Ph.D. thesis.
The thesis was apparently about “ET++”, which was an OO framework for building desktop apps written in C++. As part of the thesis, Gamma apparently created a catalogue of useful “patterns” in the creation of the framework. The catalog spun off as its own thing. The other three authors came into contact with the catalog, probably through the OOPSLA academic conferences, and they moved it into its own work and eventually to a book.
It is arguably the most influential programming book that isn’t about a specific language. (Other possibilities: XP Explained, Mythical Man-Month, Clean Code — I’ve actually never read two of those…)
It is impossible to overstate how ubiquitous this book was. I very much remember working at Motorola, circa 2005 — ten years after the book came out — and every cubicle had a copy. It’s certainly one of the few programming books to have spawned a backlash that was nearly as influential as the book itself.
To my genuine surprise, they don’t seem to have ever done a second edition. There are a bunch of offshoots, though, both official and unofficial. (Including Design Patterns in Ruby from Russ Olsen, also the author of Eloquent Ruby.)
It’s worth noting the timing here, since the book came out in 1994:
- This book predates Java, the code examples are in C++ and, much more rarely, Smalltalk. The book was a huge influence on Java, both the language and the standard library. (That’s one reason I’m surprised they never did a second edition with the code samples in Java.)
- As a result, it also pre-dates most of the 90s hype about object-oriented programming, though, the book was a contributing factor in that hype.
- But this does mean the book was written in a context that was much different than the context when most of its readers encountered it. You might argue that the book was trying to solve a problem that was largely solved by the time many of its readers got to it.
My physical copy, from 2000, is the 20th(!) printing. Wikipedia says it sold more than 500,000 copies. To provide context, that is well over an order of magnitude more than I have sold. Total. All titles.
I’m not sure when I first encountered it… actually I can check. Please hold while I dig around in dusty basement bookshelves…
My grad school work in 1997 and 1998 was using modeling software to teach Object-Oriented design, and I did, in fact, cite this book in the dissertation, so I clearly read it in 1996 or 1997.
This is 1998-me, writing about why I did not choose to include support for patterns in my modeling software. In addition to some logistical issues (the student programs were generally too simple to support patterns, I ended with this.
My experience in attempting to teach design patterns when I taught [the OO class] was that they were not particularly helpful — the students had not had any experience encountering the kinds of problems that patterns are aimed at solving, so they did not see the need for them.
It’s also possible that, as a very novice teacher, I was not doing a good job explaining things. (Somewhere in my basement I think I still have the final exam from that class, I should pull that out someday).
What’s The Big Idea?
Like a lot of these programming books, the authors lay out their thesis in an introduction that doesn’t get read by a lot of people.
We quickly get this quote:
Experienced object-oriented designers will tell you that a reusable and flexible design is difficult if not impossible to get ‘right’ the first time.
What’s striking about this sentence from a 2026 perspective is that depending on your definition of “experienced”, the number of “experienced” OO designers in the entire world when this book was being written was… pretty small. OO was still a fringe case. C++ was released in 1985, but did not have a lot of users. Smalltalk went public outside Xerox in 1981 but it wasn’t really public until 1983, and was always kind of niche. It was entirely possible to be a professional programmer in 1994 and not touch object-oriented anything.
Anyway, you were saying, Gang of Four…
One thing expert designers know not to do is solve every problem from first principles. Rather, they reuse solutions that have worked for them in the past… Consequently, you’ll find recurring patterns of classes and communication objects in many object-oriented systems. These patterns solve specific design problems and make object-oriented designs more flexible, elegant, and ultimately reusable.
There’s that “pattern” word.
I’ve threatened a few times to write about the OO hype of the 90s, and the word “reuse” was a big part of that hype cycle. 90s OO was all about chasing reuse, in the sense that business logic objects created for one program at your organization could be re-used as-is in other programs. This never really paid off in the way that it was expected to.
Off the top of my head, I think that the problem was that the 90s OO designers were thinking the wrong level. By the 2000s, Open Source was vast enough that we had extremely substantial and influential reuse, but not of individual business logic classes as much as we got it of entire foundation libraries (like, say, Rails). So, I didn’t share my User class from program to program, but I did share the underlying HTTP layer logic.
Sorry, I interrupted you again, Gang of Four, go on…
An analogy will help illustrate the point. Novelists and playwrights rarely design their plots from scratch. Instead, they follow patterns like “Tragically Flawed Hero” (MacBeth, Hamlet, etc.) or “The Romantic Novel” (countless romance novels). In the same way, object-oriented designers follow patterns like “represent states with objects” and “decorate objects so you can easily add/remove features.” Once you know the pattern, a lot of design decisions follow automatically.
I don’t necessarily thing it’s a good idea to pick on people who are likely smarter than me, and have certainly been way more influential than I have, but the idea that the only examples of novels and plays they have are Shakespeare or “countless romance novels” is just incredibly funny. I’m flip-flopping a bit on how I feel about “novelists and playwrights rarely design their plots from scratch”. I guess it’s true, or at least, truthy — what is Save The Cat if not a pattern language for screenplays? That said, I don’t think that design decisions in creative work “follow automatically”. Though I guess I don’t really think they do in OO design either.
There’s something about this analogy that feels like a category error — “The Romance Novel” does not feel, to me, like it’s at the same level as “represent states with objects”. One feels like an entire work and one feels like a trope.
Anyway, before I run away on a Romance Novel theory of OO Design, the thesis of the actual book:
- Seemingly disparate programs will have common patterns of logic or interaction.
- By identifying these patterns, and applying tried-and-true solutions to them, you end up with — well, I’ll quote them — “design patterns help a designer get a design ‘right’ faster”.
The innovation here is the idea that a “pattern” is a useful unit of design, both for the actual design and for reusing solutions in multiple problems. They don’t really define what makes a design “right” in any rigorous way, but they suggest that patterns make a design quicker to establish, easier to reuse, and more consistent. I think the implication is that by using existing solutions, bugs will also be less frequent.
I should note that the book is pretty explicit that this is just a sampling of the most commonly used patterns and that readers are encouraged to identify, name, and define common patterns in their own domain. I note that because it’s a point that frequently got lost when people started to apply the book.
Okay, but what’s a “pattern”?
All of this is based on the writings of Christopher Alexander. Alexander was an architect, and the co-author of A Pattern Langauge (1977), which is where the term “pattern language” comes from.
A “pattern language” isn’t a language in the computer sense, but a common set of patterns that all share the same structure and interact with each other. The patterns become the way you discuss the design space, so they do kind of become a language for talking about design.
A pattern typically has a name, a problem that it is trying to solve, a description of a successful solution, and a cross-reference to related patterns. Per wikipedia, Alexander’s architecture patterns include things like “a place to wait” with the problem being “people need a place to exist while they wait for a thing to happen”, and solution pieces presumably including “seating”, and “a television turned to the most annoying news station available”. I’m assuming.
What I’m quite not sure about is when the ideas about useful and reusable structures in architecture started to cross-pollinate with software. But the early software pattern writers were pretty explicit that they were trying to adapt Alexander’s work.
Book Structure
There’s a foreword by Grady Booch that is four paragraphs long and might, might, have taken upwards of an hour to write.
The book starts with the introduction containing the above quotes, some logistics, and then a bunch of sections on how patterns work and some general OO design stuff like inheritance versus composition. Then there’s a case study building a WYSIWYG editor called Lexi and showing how patterns work to help design an editor like this.
Looking at it, in some ways the case study a clearer statement of the author’s priorities than the introduction is. The chapter is 44 pages long, has something like 20 different object diagrams or interface listings, some pseudo-code, and basically zero lines of actual code logic. (That’s maybe unfair, there are code samples, but they are like if statements leading to constructors for classes not shown or straight up comments, basically all the code is showing structural logic not business logic.) This is not a book for people interested in implementation details, it’s about strategy, not tactics.
That’s fine, the book can be about structural logic, but using it does lead to a technical form of OO (see here), where the classes tend to be defined by their role in the pattern rather than their role in the domain.
Each pattern gets a consistent format with as many as 13 subsections ranging from name to sample code to known uses. We start with “Abstract Factory” also known as “Kit”, (as in “UserKit”) a term which did not make it out of the 90s but which is actually a lot easier to type than “Abstract Factory”, and good on me for writing a joke that forced me to type “Abstract Factory” again. And again.
To give a sense of the timeline here, the motivation for AbstractFactory starts with “Consider a user interface toolkit that supports multiple look-and-feel standards, such as Motif and Presentation Manager”. I’ve used AbstractFactory a lot, and I’m pretty sure that’s no longer the main use case.
I could cherry-pick stuff that didn’t age well all day. Like this consequence of AbstractFactory — “Extending abstract factories to produce new kinds of Products isn’t easy. That’s because the AbstractFactory class fixes the set of products that can be created”. True in C++, but not true in Ruby and not even true in Smalltalk in 1994. (You are all narrowly escaping a 20 part series where I dissect each of the patterns one by one. Very narrowly.)
The fact is, though, that the discussions of the individual patterns are pretty thorough. There are implementation examples, pros and cons, uses in the wild, relations to other patterns. These discussions really do make you feel like you could start applying these patterns to your code immediately. Which is both the impact and the backlash.
Because people did start applying these patterns to their code immediately whether the code warranted it or not.
Impact
To start with the concrete impact, several of the patterns were explicitly incorporated into Java, either the language or the standard library, often using the same names. (Smalltalk already had a lot of the patterns in its library, the book in some sense is a guide for how to do fun Smalltalk stuff in C++.) I’m not 100% sure what the vector was to Java, though. (None of the four actually worked on Java itself, as far as I can tell, but Erich Gamma was one of the co-creators of the JUnit test framework and also worked on Eclipse, which was one of the earliest Java IDEs.
I think there was less impact on Python and Ruby, in part because those were further along when the book came out. Both Python and Ruby have a lot of the patterns built in to their language or standard library.
Where the book was immediately successful was in changing the way people talked about their code. The naming of the patterns caught on and people very much started to explicitly look for ways to incorporate the patterns into their code.
Reaction
Let me tell a little story.
In 2000, I started a new job. The company did back end email server software. The first thing my new team wanted me to do was review the current state of a new project. A team of five had worked on it for six months. I cannot for the life of me remember what the project was.
I do remember what they asked me to review.
The deliverable was a binder. Five people, six months, and they had produced a design. And that’s it. The design was a bunch of UML diagrams, and I’m sure it included a lot of design patterns.
I don’t remember what I said publicly but I do remember what I thought privately, which is “wouldn’t the project be in better shape if people had already started coding something”.
Anyway, you can probably guess how this went, basically as soon as they started actual development they realized that one of their requirement assumptions was wrong and most of the design was not usable.
So… in my head we have a classic thesis / reaction:
Thesis: Using UML diagrams and doing a lot of design up front will improve program reuse.
Reaction: Big Design Up Front is often a waste of time, you are better off using that time to build code that is amenable to change. This technique became known as Agile, more or less.
The line between the two groups isn’t that clear-cut — Erich Gamma did work with Kent Beck on the early JUnit releases. (But none of the Gang of Four were in the original Agile Manifesto group.)
Of course, by now the two have coalesced and we have the synthesis: whatever the heck teams do now that they kind of call agile-ish and which waves in the direction of design patterns now and then.
The other kind of backlash was a more on the execution side. Based pretty much solely on my own experience, this book tended to be interpreted in two incorrect ways:
- These 20 patterns were the only patterns that existed.
- A design could be evaluated solely on how many patterns it used.
You see where this is going, or perhaps you are old enough to have been a professional in the 2000s and you lived it. Patterns everywhere! And I’m sure I indulged that myself.
The designs just got too complicated. Especially once it collided with “everything must also be an interface” design in Java. Eventually you would have an explosion of classes that often existed either to just check a box for inclusion in a pattern, or to just shuffle data around without any actual use. Since the people misinterpreting Design Patterns tended to see this complexity as a positive, it was nigh-impossible to debate them out of the patterns.
Current Status
Well, I don’t see the book around as much anymore. Quite a high percentage of the actual patterns (like “iterator” or even “abstract factory”) just became part of the way we talk about software. A few (“chain of responsibility”, “Memento”) kind of faded. But looking at the list of patterns, I’d say I’ve used or discussed about half of them in, say, the past year. That’s not a bad contribution all by itself.
What does seem to have faded is the idea that patterns will save us (or even that OO Design will save us). As for the Agile reaction, we’ll get to that…