TLDR reference
Design patterns
A searchable cheatsheet of software design patterns - the 23 Gang of Four patterns plus common modern ones - each with a short PHP snippet and a one-line intent. Type to search, or filter by group. Everything runs in your browser.
29 shown
-
Singleton
Creationalfinal class Config { private static ?self $instance = null; public static function get(): self { return self::$instance ??= new self(); } private function __construct() {} }Guarantees a single shared instance with one global access point, created lazily. Handy for config or a logger - but it hides dependencies, so prefer dependency injection where you can.
-
Factory Method
Creationalabstract class Dialog { abstract protected function createButton(): Button; public function render(): string { return $this->createButton()->html(); } }Defers which class to instantiate to a subclass via an overridable method, so the base code depends on an interface rather than a concrete type.
-
Abstract Factory
Creationalinterface UiFactory { public function button(): Button; public function checkbox(): Checkbox; } final class MacFactory implements UiFactory { /* ... */ }Creates whole families of related objects (a matching button and checkbox, say) without naming their concrete classes. Swap one factory to swap the entire set.
-
Builder
Creational$query = (new QueryBuilder()) ->select('id', 'name') ->from('users') ->where('active = true') ->build();Assembles a complex object step by step through a fluent API, separating construction from the final representation. Great for objects with many optional parts.
-
Prototype
Creational$base = new Document(theme: 'dark'); $copy = clone $base; $copy->title = 'Report';
Creates new objects by copying an existing instance instead of building from scratch. In PHP this is the built-in clone, customised via __clone().
-
Adapter
Structuralfinal class StripeAdapter implements PaymentGateway { public function __construct(private Stripe $stripe) {} public function pay(int $cents): void { $this->stripe->charge($cents / 100); } }Wraps an incompatible class so it matches the interface your code expects - the translation layer between a third-party API and your own.
-
Bridge
Structuralabstract class Notification { public function __construct(protected Channel $channel) {} } // Notification types vary independently of Channel (email, SMS).Splits an abstraction from its implementation so the two can vary independently, avoiding a class explosion such as shapes times renderers.
-
Composite
Structuralinterface Node { public function size(): int; } final class Folder implements Node { /** @var Node[] */ private array $children = []; public function size(): int { return array_sum(array_map(fn (Node $n) => $n->size(), $this->children)); } }Treats individual objects and groups of objects uniformly through one interface - the pattern behind any tree (files and folders, UI nodes).
-
Decorator
Structuralfinal class GzipStream implements Stream { public function __construct(private Stream $inner) {} public function write(string $data): void { $this->inner->write(gzencode($data)); } }Wraps an object to add behaviour at runtime without subclassing. Stack decorators to combine features such as compress, encrypt, and buffer.
-
Facade
Structuralfinal class Converter { public function toMp4(string $file): string { $codec = (new CodecFactory())->find($file); return (new VideoEncoder($codec))->run($file); } }A single simple entry point over a complicated subsystem, hiding the moving parts behind one friendly method.
-
Flyweight
Structuralfinal class GlyphFactory { /** @var array<string, Glyph> */ private array $pool = []; public function get(string $char): Glyph { return $this->pool[$char] ??= new Glyph($char); } }Shares immutable, intrinsic state across many objects to cut memory use - one Glyph per character, reused everywhere it appears.
-
Proxy
Structuralfinal class CachingRepo implements Repo { /** @var array<int, Row> */ private array $cache = []; public function __construct(private Repo $real) {} public function find(int $id): Row { return $this->cache[$id] ??= $this->real->find($id); } }Stands in for another object to control access - adding caching, lazy loading, logging, or access checks without changing the real class.
-
Chain of Responsibility
Behavioralabstract class Handler { public function __construct(private ?Handler $next = null) {} public function handle(Request $r): ?Response { return $this->next?->handle($r); } }Passes a request along a chain until a handler deals with it - the shape of middleware pipelines and event bubbling.
-
Command
Behavioralinterface Command { public function execute(): void; public function undo(): void; } final class History { /** @var Command[] */ private array $done = []; }Wraps an action as an object so you can queue, log, and undo it - the basis of undo/redo and task queues.
-
Iterator
Behavioralfunction rows(PDO $pdo): Generator { yield from $pdo->query('SELECT * FROM logs'); } foreach (rows($pdo) as $row) { /* ... */ }Walks a collection element by element without exposing its internals. PHP gives you this through Iterator and generators (yield).
-
Mediator
Behavioralinterface Mediator { public function notify(object $sender, string $event): void; } // Components talk to the mediator, never to each other.Centralises communication between components so they no longer reference each other directly, untangling many-to-many dependencies.
-
Memento
Behavioralfinal class Editor { public function save(): Snapshot { return new Snapshot($this->text); } public function restore(Snapshot $s): void { $this->text = $s->text; } }Captures an object snapshot so it can be restored later, without exposing its internals. Powers save points and undo.
-
Observer
Behavioralfinal class Subject { /** @var callable[] */ private array $listeners = []; public function subscribe(callable $fn): void { $this->listeners[] = $fn; } public function emit(mixed $event): void { foreach ($this->listeners as $fn) { $fn($event); } } }Lets objects subscribe to and be notified of changes in another object - the publish/subscribe core of event systems.
-
State
Behavioralinterface State { public function next(Order $o): void; } final class Pending implements State { /* -> Shipped */ } final class Shipped implements State { /* -> Delivered */ }Lets an object change behaviour when its internal state changes by delegating to a state object - replaces sprawling switch statements.
-
Strategy
Behavioralfinal class Cart { public function __construct(private Discount $discount) {} public function total(int $sum): int { return $this->discount->apply($sum); } }Swaps an algorithm at runtime by injecting one of several interchangeable implementations behind a common interface.
-
Template Method
Behavioralabstract class Importer { final public function run(string $file): void { $rows = $this->parse($file); $this->store($rows); } abstract protected function parse(string $file): array; }Defines the skeleton of an algorithm in a base method, letting subclasses fill in specific steps without changing the overall flow.
-
Visitor
Behavioralinterface Visitor { public function visitCircle(Circle $c): float; public function visitSquare(Square $s): float; } // Each shape calls $visitor->visitX($this).Adds new operations to a set of classes without modifying them, by moving the logic into a visitor. Good for stable hierarchies with changing operations.
-
Interpreter
Behavioralinterface Expr { public function eval(array $ctx): bool; } final class AndExpr implements Expr { /* a && b */ }Represents a small language as a tree of expression objects that evaluate themselves - used for rules engines and query filters.
-
Dependency Injection
Modern & architecturalfinal class ReportService { public function __construct( private Mailer $mailer, private Repo $repo, ) {} }Hands an object its dependencies from outside (usually via the constructor) instead of letting it create them - the backbone of the Symfony container, and what makes code testable.
-
Repository
Modern & architecturalinterface UserRepository { public function find(int $id): ?User; public function save(User $user): void; }Wraps data access behind a collection-like interface, so domain code never sees SQL or the ORM. Swap the storage without touching business logic.
-
Null Object
Modern & architecturalfinal class NullLogger implements Logger { public function log(string $message): void {} }A do-nothing implementation of an interface, used in place of null so callers skip endless null checks. PSR-3 ships exactly this.
-
Service Locator
Modern & architecturalfinal class Locator { /** @var array<string, object> */ private array $services = []; public function get(string $id): object { return $this->services[$id]; } }A registry you ask for dependencies by name. Flexible, but it hides what a class actually needs - generally prefer dependency injection.
-
MVC
Modern & architectural// Model: data + rules (User, UserRepository) // View: templates (user/show.html.twig) // Controller: maps a request to the model + a view
Separates data (Model), presentation (View), and request handling (Controller) so each can change independently - the shape of most web frameworks.
-
Specification
Modern & architecturalinterface Spec { public function isSatisfiedBy(object $candidate): bool; } $eligible = $premium->and($active);Encapsulates a business rule as an object you can test, combine (and/or/not), and reuse for filtering or validation.
No patterns match your search.
How it works
A searchable cheatsheet of software design patterns: the 23 classic Gang of Four patterns - grouped into Creational, Structural, and Behavioral - plus a handful of modern, architectural ones such as Dependency Injection, Repository, and Specification. Each card pairs the pattern name with a short PHP snippet showing its shape and a one-line note on what it does and when to reach for it. Type to search by name or idea - "singleton", "observer", "wrap", "undo" - or use the chips to browse one group.
The snippets are PHP, but the ideas are language-agnostic: a pattern is a named, reusable solution to a recurring design problem, and a shared vocabulary for talking about structure. Use this as a quick refresher before an interview, a nudge when a class is getting tangled, or a map of the options when you are not sure which shape fits. Everything is static and runs in your browser, so the lookup is instant and works offline once the page has loaded.
Example. Searching "factory" lines up the creational options: a Factory Method defers the choice of class to a subclass, while an Abstract Factory builds a whole family of matching objects. Filtering by the Behavioral chip groups the patterns that manage how objects collaborate - Observer, Strategy, Command, State - so you can compare the ones that solve similar problems side by side.
FAQ
What are the three Gang of Four pattern categories?
The original 23 patterns from the "Design Patterns" book are split into three groups by what they are about. Creational patterns deal with how objects are made (Singleton, Factory Method, Abstract Factory, Builder, Prototype). Structural patterns deal with how objects are composed into larger structures (Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy). Behavioral patterns deal with how objects communicate and share responsibility (Observer, Strategy, Command, State, and the rest). This cheatsheet adds a fourth group for widely-used modern and architectural patterns that came later.
Are these patterns specific to PHP?
No. Design patterns are language-agnostic solutions to recurring design problems - they apply to any object-oriented language, from Java and C# to Python and TypeScript. The snippets here are written in PHP because that is what this site is built in, but the structure is what matters, not the syntax. A few patterns are nearly invisible in some languages because the language already provides them: PHP gives you Prototype through clone and Iterator through generators, for example.
What is the difference between the Singleton pattern and dependency injection?
Both give you a single shared instance, but they differ in who is in control. A Singleton creates and hands out its own instance through a global static method, so any class can reach for it from anywhere - which hides the dependency and makes the code hard to test in isolation. Dependency injection instead passes the shared instance in from outside, usually through the constructor, so a class declares what it needs and a container wires it up. In modern frameworks like Symfony you almost always want dependency injection; the container already guarantees one shared instance per service.
Do I need to memorise all 23 patterns?
No. The value is in recognising the shape of a problem and knowing a proven solution exists, not in reciting definitions. A handful come up constantly - Strategy, Observer, Factory, Adapter, Decorator, and Dependency Injection - and are worth knowing well. The rest are useful to recognise so that when you meet one in a codebase or need one, you know what to look up. Patterns are a vocabulary, not a checklist: reach for one because it fits, not to tick a box.