Case file PT1

Patterns Are Vocabulary

Name them out loud, and in the code.

Patterns are the words two engineers use at the whiteboard so they do not have to describe a thing from first principles. The vocabulary works only if both speakers know the words, and only if the words also live in the code.

ByAdam LewisPublished3 May 2026Revised13 Oct 2026Reading11 minVersionv1.2ConfidenceHigh
§0b

Opinion

I've sat through enough whiteboard sessions where someone said “let's use a strategy here” and meant five different things by it to know that the GoF book's original gift was not the patterns. It was the words.1 Strategy. Factory. Repository. Visitor. The vocabulary is the value. A Factory called OrderCreator is a Factory the next reader has to discover by reading. A class called OrderFactory announces itself in ls.

The naming rule is small and it has teeth. A class that produces instances is a Factory rather than a Creator, a Provider or a Maker. Those words mean different things in the catalogue and conflating them makes the catalogue useless.2 A class that observes is an Observer rather than a Listener, unless the framework demands it. A class that adapts is an Adapter, a class that simplifies is a Facade and a class that controls access is a Proxy. Pick the one whose semantics match. This is F2 Intention-Revealing Names applied at the pattern layer.

The corollary nobody likes: read the catalogue once and stop. Strategy was written better in 1994. Repository was written better by Fowler in 2002. POODR explained the inheritance trap better than I will.3 Cite, do not paraphrase: the catalogue is somebody else's lifetime of work and rewriting it would be the wrong abstraction. The job here is to get the vocabulary into the code.

Copy a note and link

Grab this short comment and drop it into a PR comment or an LLM chat to prompt the right change.

If a class implements a known pattern, name it for that pattern. A Factory is `*Factory`. A Repository is `*Repository`. The pattern's name belongs in the identifier, not just the conversation. If you can't name the pattern, you may not have one: don't manufacture one.

/tenet/patterns-are-vocabulary/PT1
Copy for paste
§0c

AI eyes only

Rule: name patterns out loud, in code. If it acts like a Factory, call it a Factory.

Reject: a textbook Repository named OrderStore. Reject: a textbook Adapter named Wrapper. Reject: claiming a pattern when only the shape coincides.

Generate: when emitting a class or module that fits a textbook pattern, name it after the pattern (UserRepository, PaymentAdapter). When two functions only happen to share shape, do not invoke the pattern.

Diagnostic: state the pattern out loud and recite its Intent. If the recited Intent matches what the code does, the name is right. If it does not, do not invoke the pattern.

§0d

Why?

  • Two engineers at a whiteboard say “Strategy” and mean the same thing. The GoF catalogue's lasting contribution is the words; PT1 keeps them earning their keep in the code.
  • ls becomes a glossary. order-factory.ts, order-repository.ts, order-observer.ts tell the next reader where the design is before they open a file.
  • Pairs with F2 Intention-Revealing Names: F2 says the signature is the spec; PT1 says the pattern is part of the signature.
  • The linter reaches into the patterns layer through naming and nothing else. @typescript-eslint/naming-convention, Ruff's N801, PMD's ClassNamingConventions: the suffix rule is enforceable. The rest of the pattern isn't.
  • Review conversations stop being archaeology. “Where's the Factory?” is a one-grep question. Review time goes to design, not to file-tree navigation.
  • Agents have read every catalogue and know the names. The CLAUDE.md instruction “if it acts like a Factory, call it a Factory” closes the gap between the agent's knowledge and the codebase's nomenclature.
  • Read the catalogue once and stop. GoF, refactoring.guru, Fowler and Metz wrote it down. The team's job is to use the words, not rewrite them. The pillar is a curator, not an author.
The receipts
Origins, quoted passages, evidence, the strongest counter-argument and the reply.
§1

Origins

The pattern catalogue arrived in 1994 with Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides's Design Patterns: Elements of Reusable Object-Oriented Software, the “Gang of Four” book.1 The book's lasting contribution wasn't the twenty-three patterns themselves, most of which had been observed in working systems for years, but the thirteen-section template (Intent, Motivation, Applicability, Structure, Participants and Consequences among them) and, above all, the names. Strategy. Singleton. Visitor. Factory Method. Without the names, two engineers describing the same thing had to start from scratch every time.

Christopher Alexander's A Pattern Language (1977) is the architectural forebear the GoF authors cite directly: a pattern names a recurring problem and a vocabulary for its solution.7 Kent Beck's Smalltalk Best Practice Patterns (1996) held the naming-as-design discipline forward into the OO mainstream, and Sandi Metz's POODR (2012; 2nd ed. 2018) is the most thorough single treatment of when not to reach for a pattern, and what the right names look like when you do.3

Martin Fowler's Patterns of Enterprise Application Architecture (2002) extended the catalogue upward to the architectural layer (Repository, Unit of Work, Data Mapper, Active Record) and made those names load-bearing in every web framework written since.8 The modern accessible reference is refactoring.guru: free, illustrated, the entry point most engineers under thirty-five reach for first. Refactoring Guru is what teams cite in code review now. The GoF book is what the citations point at.

The naming-rule half of PT1 is older still. Brian Kernighan and P. J. Plauger's The Elements of Programming Style (1974) puts it in five words: “say what you mean, simply.”9 Decades before Clean Code, the discipline of letting the identifier hold the design was in print. PT1 is that rule plus the catalogue: the name says what it is and the name has to match the canonical word the catalogue already gave us.

§2

Quotes

Each design pattern systematically names, explains, and evaluates an important and recurring design in object-oriented systems.

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides · Design Patterns (1994), ch. 1

Informal: Design pattern in prose; refer to by name, but must be implemented from scratch for each use

Peter Norvig · Design Patterns in Dynamic Languages (1996)

Pattern misapplication results in complicated and confusing code, but this result is not the fault of the pattern itself. A tool cannot be faulted for its use; the user must master the tool.

Sandi Metz · POODR, 2nd ed. (2018)

Instead of compensating for poor variable, method, class, or test names, rename them.

Kevlin Henney · Comment Only What the Code Cannot Say (2010)
§3

Evidence

16 external sources, ranked by author authority. The first five are the canon; expand to see the rest, including the qualifiers and the named opposers. Each links out to its primary source.

  1. 01
    Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides · 1994
    The book that gave the industry the words. The 23 patterns are a vocabulary. The lasting contribution is the names (Strategy, Singleton, Visitor, Factory) that two engineers can use without describing the thing from first principles.
  2. 02
    Refactoring Guru · 2014 onwards
    The free, illustrated, modern walkthrough of the GoF patterns plus Fowler's refactorings. The reference most engineers under thirty-five reach for first. Supports the naming-as-vocabulary rule with worked examples in ten languages.
  3. 03
    Martin Fowler · 2002
    Extends the GoF vocabulary upward to the architectural layer. Repository, Unit of Work, Data Mapper, Active Record: every web framework written since uses these names. Confirms vocabulary is the lasting contribution.
  4. 04
    Kent Beck · 1996
    Post-GoF treatment of naming-as-design. Treats names as primary. The word in the identifier holds the design intent. The closest predecessor to PT1's naming rule.
  5. 05
    Sandi Metz · 2009; 2nd ed. 2018
    The deepest single treatment of when not to reach for a pattern. Naming is part of the discipline, but Metz's rule is to name only when the pattern is real, never to manufacture one for the sake of vocabulary.
  1. 06
    Christopher Alexander · 1977
    The architectural-design forebear the GoF authors cite directly. A pattern names a recurring problem and a vocabulary for its solution. Without the name, the solution can't be reused across teams.
  2. 07
    Peter Norvig · 1996
    The strongest steelman. In a language with first-class functions and dynamic dispatch, sixteen of the twenty-three GoF patterns become invisible or one-liners. The reply: the vocabulary outlives the class hierarchy.
  3. 08
    Steve Yegge · 2006
    The cultural-not-technical critique. Treating every concept as a noun-class produces ceremonial code. Pattern-as-class-name is one of the bars. PT1's reply is to make the rule descriptive, not coercive.
  4. 09
    typescript-eslint maintainers · 2019 onwards
    The lint hook that makes the naming rule enforceable in TypeScript. Suffixes, prefixes, casing: all configurable. The only foothold linters get inside the patterns layer.
  5. 10
    Astral / Ruff team · 2022 onwards
    Ruff's Python equivalent of the naming-convention rule. Confirms the lint exception generalises across language ecosystems. Not a TypeScript peculiarity.
  6. 11
    PMD project · 2002 onwards
    Java equivalent. ClassNamingConventions is one rule with a regex per kind of declaration: classPattern, abstractClassPattern, interfacePattern, enumPattern, annotationPattern, utilityClassPattern, testClassPattern. The Java ecosystem treats this as routine; PT1 says the same instinct should be universal.
  7. 12
    Kevlin Henney · 2010
    Vocabulary in identifiers, prose for what they can't carry. Henney's distinction supports PT1: name what the pattern is. If the name doesn't hold it, fix the name first.
  8. 13
    Bob Nystrom · 2014
    GoF reframed for game developers, with sharper prose and concrete examples. Every chapter opens with the canonical pattern name. Demonstrates the vocabulary is portable across application domains.
  9. 14
    Wikipedia contributors · 2024
    Includes the famous note that Erich Gamma said in 2009 he would remove Singleton from a revised GoF. The vocabulary persists. Specific patterns can age out (cross-link PT3).
  10. 15
    Steve Yegge · 2004
    The case that Visitor exists because OO can't double-dispatch: the vocabulary masks a type-system surrender. Naming the Visitor 'Visitor' makes the surrender visible (which is the right outcome).
  11. 16
    Joshua Bloch · 2017
    Item 1 “Consider static factory methods instead of constructors”: explicit on the convention names (from / of / valueOf / instance / getInstance / create / newInstance). The naming discipline at industrial scale.

Sixteen sources, three stances. The supporters are the canon: Gamma et al. (GoF), Refactoring Guru, Fowler's PoEAA and Beck's Smalltalk Best Practice Patterns. The qualifiers further down hold the “name the right thing” nuance: name a pattern only when it is real, never manufacture one for the sake of vocabulary. The opposers are the ones the reply has to address: when the pattern is just a function, naming it as a pattern is ceremony.

§4

Examples

Viewing: TypeScript.
Avoid

Before the class is a Factory, but ls -la cannot tell.

Filehedgehog-maker.ts
export class HedgehogMaker {
  make(name: string, prickleCount: number): Hedgehog {
    return new Hedgehog(name, prickleCount);
  }
}
Prefer

After the pattern name lives in the type and the file.

Filehedgehog-factory.ts
export interface Factory<T> { create(...args: readonly unknown[]): T; }

export class HedgehogFactory implements Factory<Hedgehog> {
  create(name: string, prickleCount: number): Hedgehog {
    return new Hedgehog(name, prickleCount);
  }
}
§4c

AI rules

File.cursor/rules/pt1-patterns-are-vocabulary.mdc
---
alwaysApply: true
---

## Prickles PT1: Patterns Are Vocabulary

If a class implements a known pattern, name the pattern in the identifier. A Factory is `*Factory`. A Repository is `*Repository`. An Adapter is `*Adapter`. An Observer is `*Observer`. An abstract base is `Abstract*` or marked `abstract` in the language.

Read GoF, Refactoring Guru, or Fowler's PoEAA once so the names mean the same thing across team and code. Do not paraphrase the catalogue. Cite it.

Refuse to introduce a pattern unless the pattern is unmistakable from the requirement. When the pattern is real, name it. When it isn't, don't manufacture one.

If you discover the code already implements a pattern after the fact, rename it to the canonical word. A Repository called `OrderStore` is a missed signal. Rename it `OrderRepository`.

Repo layout, CI, and ESLint wiring for these paths live on /implementation, not repeated on every tenet.

§5

Counter-argument

Counter

The strongest steelman is Peter Norvig's.4 In a language with first-class functions and dynamic dispatch, sixteen of the twenty-three GoF patterns become invisible or one-liners: Strategy is a function passed as an argument; Iterator is a generator; Command is a closure. Insisting on the GoF vocabulary in those cases is performing patterns rather than using them and the “call a Factory a Factory” rule risks pushing teams toward Java-shaped class hierarchies in languages that explicitly do not need them. Steve Yegge sharpens the same point: the kingdom of nouns is a cage, and pattern-as-class-name is one of its bars.5

§6

Counter-argument retort

Reply

Norvig is right about dynamic-language patterns and the rule still stands. The vocabulary isn't the class hierarchy but the word itself. A higher-order function that produces an instance is still a Factory. Naming the file order-factory.ts when the export is a function called createOrder tells the reviewer this is the place new orders come from: the same signal a class would carry, without the ceremony Norvig objects to.4

Yegge's “kingdom of nouns” argument5 is the harder one and the reply is to treat the vocabulary as descriptive, not coercive. PT1 doesn't say “turn every function into a noun-class.” It says “if you've already got a Repository, call it one.” A team writing functional TypeScript that has zero classes still has Repositories: they're modules withfind / save / delete exports talking to a store. Naming the module order-repository.ts justifies itself the same way the class name would. The vocabulary is the constraint that survives the language change.

The genuine residue is the over-naming risk: calling a function a Strategy because two callers exist. The naming half of PT1 doesn't solve that. The other half does. PT1 says: when the pattern is real, name it. It also says: don't manufacture patterns from coincidence. Both halves are needed. Neither is sufficient on its own. The reviewer's question becomes “is this a Strategy, and if so why isn't it called one?”: one question, two rules behind it.

One lint rule reaches into this layer. ESLint's @typescript-eslint/naming-convention, Ruff's N801, PMD's ClassNamingConventions: the first and third can require a prefix or suffix by kind of class (abstract or exported in ESLint; abstract, utility or test in PMD), and N801 only checks that a class name is CapWords.6 That is the only foothold linters have inside the patterns layer. Everything else (pattern misuse, anti-pattern detection, “you should have used Strategy here”) is unreachable to static analysis. TA1 Linter as Law names the boundary and PT1 is the only place the tooling reaches across it.

§7

Notes

  1. [1]Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994). The lasting contribution is the names: Strategy, Singleton, Visitor, Factory. Without the words, the patterns would have been re-invented in every team rather than reused.
  2. [2]Refactoring Guru: Design Patterns reference (refactoring.guru/design-patterns). Each entry names the pattern, its intent, its structure, and crucially the conventional class-name suffix or prefix that flags an instance of the pattern in code review.
  3. [3]Sandi Metz: Practical Object-Oriented Design in Ruby (POODR), 2nd ed. (2018). The deepest single treatment of when not to reach for a pattern; Chapter 6 on inheritance is the canonical statement that a pattern misnamed is a pattern misused.
Disagree? Found a hole in the argument? Take issue with this tenet →
Last revised: 2026-10-13