Карта 23 классических паттернов проектирования Gang of Four + JS-специфичные расширения. Подход автора а: паттерны GoF — это не структура классов, а проблема + способ её решения.
Главные тезисы автора
- Паттерн = проблема + способ решения. Код может быть любой — главное, что решается та же проблема тем же способом.
- GoF — это про структуру кода в одном процессе, не про архитектуру. Архитектурой занимаются Enterprise Patterns и выше.
- В динамических языках паттерны схлопываются. Adapter, Decorator, Proxy, Facade по коду в JS почти неотличимы — различает их интенция.
- Структурные паттерны = композиция классов. Все они хранят внутри ссылку на другой инстанс (или замыкание).
- GoF писались для C++/Java. В JS многие реализуются проще: через функции первого класса, замыкания, прототипы, модули.
- Не каждый код, похожий на паттерн, — паттерн. Если решение не переиспользуется — это просто код.
Creational (порождающие)
| Паттерн |
Идея |
Заметка |
| Factory |
Сборка объекта из «трэша» (литералы, миксины, обёртки) — не из GoF, но повсюду в JS |
Factory Pattern |
| Abstract Factory |
Семейство фабрик под несколько платформ (iOS/Android/Web), универсальный код не знает платформу |
Abstract Factory Pattern |
| Builder |
Шаги инициализации через чейнинг obj.setX.setY.build. Query builder — типичный пример |
Builder Pattern |
| Prototype |
Клонирование экземпляров (structuredClone, JSON.parse(JSON.stringify)) вместо инициализации |
Prototype Pattern |
| Singleton |
Один экземпляр на процесс. В JS — через ES-модули (export default new X). Часто антипаттерн |
Singleton Pattern |
| + Object Pool |
Преаллокация N инстансов, переиспользование. Не из GoF, но важно для пулов соединений |
Object Pool Pattern |
| + Multiton |
Singleton с ограничением N экземпляров. Расширение Singleton |
(в Singleton) |
Structural (структурные)
| Паттерн |
Идея |
Заметка |
| Adapter |
Конвертирует один контракт в другой. promisify/callbackify — классические адаптеры |
Adapter Pattern |
| Bridge |
Разделяет 2+ иерархии наследования, избегая комбинаторного взрыва |
Bridge Pattern |
| Composite |
Единый интерфейс к дереву (лист, узел, всё дерево). Пример — DOM |
Composite Pattern |
| Decorator |
Расширение без наследования. Добавляет метаданные и поведение. В JS — синтаксис декораторов |
Decorator Pattern |
| Facade |
Простой интерфейс к сложной подсистеме. Главный паттерн для архитектурных границ |
Facade Pattern |
| Flyweight |
Экономия памяти: общее состояние — в эталоне, уникальное — в инстансе. В JS — через прототипы |
Flyweight Pattern |
| Proxy |
Перехват доступа к объекту. В JS — встроенный new Proxy |
Proxy Pattern |
| + Wrapper / Boxing |
Функция-обёртка или класс-контейнер над значением. Adapter для функций |
Wrapper Boxing Pattern |
Behavioral (поведенческие)
| Паттерн |
Идея |
Заметка |
| Chain of Responsibility |
Запрос идёт по цепочке обработчиков, один берёт ответственность |
Chain of Responsibility Pattern |
| Command |
Запрос как объект (data + execute). Сериализуем, лог, undo. Основа CQRS/Event Sourcing |
Command Pattern |
| Interpreter |
AST + DSL. От парсинга email до своего языка программирования |
Interpreter Pattern |
| Iterator |
Унифицированный обход коллекции/потока. В JS — Symbol.iterator, for await |
Iterator Pattern |
| Mediator |
Топология «звезда» вместо «все со всеми». Централизация связей |
Mediator Pattern |
| Memento |
Снэпшоты состояния + откат. Основа Saga и Transaction Script |
Memento Pattern |
| Observer |
Подписка на события. В JS — EventEmitter (Node) и EventTarget (browser) |
Observer Pattern |
| State |
Конечный автомат. Метод = дуга в графе переходов |
State Pattern |
| Strategy |
Коллекция взаимозаменяемых алгоритмов. В JS — объект с функциями по ключу |
Strategy Pattern |
| Template Method |
Алгоритм с шагами, наследник переопределяет шаги. Основа Transaction Script |
Template Method Pattern |
| Visitor |
Алгоритм отдельно от структуры. Новые операции без правок таргета |
Visitor Pattern |
JS-Specific (вне GoF)
| Паттерн |
Идея |
Заметка |
| Revealing Constructor |
Функция в конструктор (new Promise((res, rej) => ...)). Замена наследования |
Revealing Constructor |
| Async Adapters |
promisify, callbackify, asyncify — адаптеры контрактов асинхронности |
Async Adapters |
| Mixins |
Object.assign, классовый миксин — расширение без наследования |
Миксины (Mixins) |
| Middleware (антипаттерн) |
Цепочка обработчиков через shared state. Автор утверждает антипаттерном в 2026 |
Middleware Pattern |
| Wrapper (HOF) |
Функция-обёртка с before/after. Базовая идея адаптера/декоратора в JS |
(см. Wrapper Boxing) |
| Reactor |
Event loop через очередь задач — основа Node.js и браузера |
Reactor Pattern |
| Proactor |
Развитие Reactor: в очередь кладётся fn + callback вместе |
Proactor Pattern |
| Actor |
Изолированное состояние, общение через очередь сообщений |
Actor Pattern |
| Async Pool |
Object Pool с await для ожидания свободного инстанса |
Async Pool |
Концептуальные заметки
Принципы определения паттерна (по автору)
- У паттерна есть проблема (что решает) и способ (как решает).
- Если совпадают проблема + способ — это тот паттерн, даже если код выглядит иначе.
- Если решение не переиспользуемо — это не паттерн, это просто код.
- В JS паттерны можно реализовать тремя стилями: на классах, на прототипах, на функциях. Часто все три эквивалентны.
Что часто путают
| Похожи, но разные |
| Adapter vs Facade: adapter — одна абстракция за другой; facade — много абстракций за одной |
| Bridge vs Mediator: bridge разделяет иерархии; mediator не знает об иерархиях |
| Composite vs Facade: composite — дерево похожих узлов с одним интерфейсом; facade — несвязанные подсистемы |
| Flyweight vs Proxy: flyweight экономит память через общее состояние; proxy перехватывает доступ |
| Decorator vs Proxy: decorator добавляет метаданные/поведение; proxy контролирует доступ |
| Middleware vs Chain of Responsibility: CoR — один берёт ответственность; middleware — каждый что-то делает (опасно) |
| Декоратор-синтаксис vs GoF-Decorator: синтаксис языка ≠ GoF-паттерн, хоть решают похожее |
Связанные домены
🎓 Источники