VK Cloud

Паттерны проектирования GoF: полный разбор по группам

30 октября 2026 г.
268267_007n7ek.jpg
Евгений Левашов
Автор статьи
_blog_head_10.png

В 1994 году Эрих Гамма, Ричард Хелм, Ральф Джонсон и Джон Влиссидес выпустили в издательстве Addison-Wesley книгу «Design Patterns: Elements of Reusable Object-Oriented Software». За авторами закрепилось прозвище «Банда четырёх» (Gang of Four, GoF), а описанные в книге 23 паттерна проектирования стали общим словарём разработчиков. Сегодня это обязательная тема собеседований и основа решений от монолита до распределённых систем. Ниже разбираем все 23 шаблона проектирования по трём группам: когда применять, чем похожие паттерны отличаются друг от друга и как они соотносятся с паттернами микросервисной архитектуры.

Важно знать
  • Книга «Банды четырёх» делит 23 паттерна на три группы: порождающие отвечают за создание объектов, структурные — за их объединение, поведенческие — за обмен сообщениями.
  • GoF-паттерны описывают устройство классов внутри одного сервиса, а архитектурные (Saga, CQRS, Circuit Breaker) — взаимодействие сервисов по сети.
  • В повседневной работе активно используются 8–10 шаблонов: Singleton, Factory Method, Builder, Adapter, Decorator, Proxy, Observer, Strategy, Command.
  • Часть инфраструктурных решений повторяет GoF на другом масштабе: API Gateway воспроизводит идею Facade, Sidecar — Decorator, service mesh — Proxy.

Паттерн проектирования — типовое решение повторяющейся задачи в коде, описанное через роли классов и объектов, а не через конкретную реализацию. GoF-паттерны получили название по книге «Банды четырёх»: именно она закрепила общий словарь и разделила 23 шаблона проектирования на три категории — порождающие (creational), структурные (structural) и поведенческие (behavioral).

КатегорияПаттерныЗадача
ПорождающиеSingleton, Factory Method, Abstract Factory, Builder, PrototypeСоздание объектов
СтруктурныеAdapter, Bridge, Composite, Decorator, Facade, Flyweight, ProxyОрганизация классов
ПоведенческиеChain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor, InterpreterВзаимодействие объектов
Важно знать

Важно не путать два уровня. GoF-паттерны живут внутри одного сервиса или модуля: они описывают, как классы и объекты в вашем процессе создаются, связываются и обмениваются сообщениями. Архитектурные паттерны вроде Saga, CQRS или Circuit Breaker работают уровнем выше: они описывают взаимодействие сервисов по сети, где нет общей памяти, общих транзакций и мгновенных вызовов. Часть архитектурных решений прямо наследует идеи GoF, но масштаб и цена ошибки у них другие.

Порождающие паттерны управляют созданием объектов и прячут логику инстанцирования от вызывающего кода. Клиент получает готовый объект и не знает, какой конкретный класс за ним стоит.

1. Singleton

Паттерн Singleton гарантирует, что в приложении существует ровно один экземпляр класса, и даёт к нему глобальную точку доступа. Типичные кандидаты: пул соединений с базой данных, логгер, объект конфигурации. Общее у них одно: такие объекты дорого создавать и бессмысленно дублировать.

Главная сложность — глобальное состояние. Класс с единственным экземпляром тяжело подменить в тестах: состояние протекает между тест-кейсами, а порядок выполнения начинает влиять на результат. В сервисах, которые собираются из компонентов, роль Singleton обычно берёт на себя DI-контейнер фреймворка. Он создаёт объект в единственном экземпляре, но отдаёт его через явную зависимость, а не через глобальную переменную.

Thread-safe вариант с двойной проверкой на Python:

import threading class ConnectionPool: _instance = None _lock = threading.Lock() def __new__(cls, *args, **kwargs): if cls._instance is None: with cls._lock: if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance

Блокировка берётся только на первом создании: последующие вызовы видят заполненный _instance и выходят без синхронизации.

2. Factory Method

Factory Method выносит создание объекта в отдельный метод, который переопределяют подклассы. Базовый класс работает с интерфейсом продукта и не знает, какой конкретный тип вернётся.

Паттерн Factory нужен там, где тип объекта определяется в runtime: по настройке, по содержимому запроса, по типу события. Классический пример — фабрика уведомлений. Сервис вызывает create_notifier(channel) и получает объект для Email, SMS или Push. Добавление четвёртого канала не трогает код отправки: появляется новый класс и новая ветка в фабрике.

3. Abstract Factory

Abstract Factory делает шаг дальше: создаёт не один объект, а целое семейство связанных объектов, которые должны использоваться вместе.

Отличие от Factory Method формулируется одной фразой: Factory Method производит один продукт, Abstract Factory — согласованный набор продуктов. Если приложение поддерживает несколько СУБД, абстрактная фабрика отдаёт сразу связку «соединение + построитель запросов + маппер типов», и собрать несовместимую комбинацию из PostgreSQL-соединения и чужого диалекта запросов уже не получится. Та же логика работает для UI-компонентов под разные платформы.

4. Builder

Builder собирает сложный объект пошагово, отделяя процесс сборки от представления результата. Паттерн выручает, когда у объекта много необязательных параметров и конструктор на десять аргументов превращается в ребус.

Типичный сценарий — построение HTTP- или SQL-запроса через цепочку вызовов:

req := NewRequest("POST", "/v1/orders"). Header("Content-Type", "application/json"). Timeout(5 * time.Second). Retry(3). Body(payload). Build()

Каждый шаг читается как предложение, порядок шагов свободный, а обязательные поля проверяются один раз в Build(). Конфигурации контейнеров и клиентов к внешним API описываются так же.

5. Prototype

Prototype создаёт новый объект клонированием существующего вместо вызова конструктора. Смысл в экономии: если инициализация дорогая (разбор схемы, прогрев кэша, чтение из сети), дешевле один раз построить эталон и дальше копировать его.

Паттерн уместен, когда нужны десятки почти одинаковых объектов с небольшими отличиями: шаблон документа, заготовка конфигурации, предзаполненный объект запроса. Ключевой вопрос при реализации — глубина копирования: поверхностный клон разделит вложенные структуры с оригиналом, и правка копии изменит эталон.


Структурные паттерны описывают, как объединять классы и объекты в более крупные структуры, сохраняя гибкость. Здесь же лежат ближайшие родственники инфраструктурных решений: несколько структурных шаблонов повторяются в микросервисах почти дословно.

6. Adapter

Adapter — обёртка, которая приводит несовместимый интерфейс к тому, которого ждёт клиентский код. Внутри адаптера живёт перевод: переименование полей, конвертация форматов, склейка нескольких вызовов в один.

Два частых случая: работа с legacy-API, который нельзя менять, и подключение сторонней платёжной системы со своим протоколом. Домен приложения при этом не обрастает чужими структурами данных.

На архитектурном уровне этой же идее соответствует Anti-Corruption Layer: отдельный слой между вашим сервисом и внешней системой, который не пускает чужую модель данных внутрь вашего домена.

7. Bridge

Bridge разделяет абстракцию и реализацию, чтобы они менялись независимо. Вместо наследования, где каждое новое сочетание требует нового класса, абстракция держит ссылку на объект реализации.

Паттерн нужен при нескольких ортогональных измерениях изменений. Если у вас три типа отчётов и четыре способа доставки, наследование даёт двенадцать классов, мост — семь: три абстракции и четыре реализации. Добавление пятого канала доставки добавляет один класс вместо трёх.

8. Composite

Composite выстраивает объекты в дерево и даёт одинаковый интерфейс для листа и для узла с потомками. Клиент вызывает один метод и не выясняет, работает он с одиночным объектом или с группой.

Канонический пример — файловая система: у файла и папки общий интерфейс с методом «вычислить размер», и папка рекурсивно опрашивает содержимое. Так же устроены деревья UI-компонентов и вложенные правила валидации.

9. Decorator

Decorator добавляет объекту поведение через обёртку, не трогая его класс. Декоратор реализует тот же интерфейс, что и вложенный объект, выполняет свою часть работы и передаёт вызов дальше.

Самый наглядный пример — middleware в HTTP-конвейере: логирование, авторизация, кэш, обработчик. Каждый слой ничего не знает о соседях, а порядок задаётся в одном месте сборки.

type Handler func(w http.ResponseWriter, r *http.Request) func WithLogging(next Handler) Handler { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() next(w, r) log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start)) } } // handler := WithLogging(WithAuth(WithCache(businessHandler)))

Инфраструктурный аналог — Sidecar: контейнер рядом с основным приложением добавляет ему телеметрию, шифрование трафика или перезагрузку конфигурации, не меняя код сервиса.

10. Facade

Facade даёт простой интерфейс к сложной подсистеме. Клиент получает три понятных метода вместо двадцати низкоуровневых, а внутренности остаются скрытыми и свободными для рефакторинга.

Пример — SDK для облачного объектного хранилища: снаружи upload(file), внутри подписание запроса, многочастная загрузка, повторы при сетевых сбоях и разбор кодов ответа.

Архитектурный аналог — API Gateway: одна точка входа для клиента, за которой прячется десяток внутренних сервисов со своими протоколами и схемами авторизации.

11. Flyweight

Flyweight экономит память, вынося общее состояние множества мелких объектов в разделяемые экземпляры. У объекта остаётся только внутреннее состояние, одинаковое для всех, а изменяемая часть передаётся снаружи при вызове.

Классика жанра — символы в текстовом редакторе: описание глифа хранится один раз, а позиция в документе передаётся параметром. Та же схема работает для спрайтов в играх и для справочных значений, которые повторяются в миллионах записей.

12. Proxy

Proxy — объект-заместитель с тем же интерфейсом, что у настоящего объекта, контролирующий доступ к нему. Клиент не отличает прокси от оригинала.

Четыре типовых разновидности:

  • virtual — откладывает дорогое создание объекта до первого реального обращения;
  • protection — проверяет права перед вызовом;
  • remote — прячет сетевой вызов за локальным интерфейсом;
  • caching — отдаёт сохранённый результат вместо повторного обращения.

На уровне инфраструктуры это service mesh: прокси Envoy, которым управляет Istio, перехватывает весь трафик пода и берёт на себя маршрутизацию, повторы, шифрование и сбор метрик.


Поведенческие паттерны описывают, как объекты распределяют обязанности и обмениваются сообщениями. Эта группа самая большая: 11 шаблонов из 23. О паттернах уровня архитектуры — в статье «26 основных паттернов микросервисной разработки».

13. Chain of Responsibility

Chain of Responsibility выстраивает цепочку обработчиков, каждый из которых либо обрабатывает запрос, либо передаёт его дальше. Отправитель не знает, кто именно ответит.

Типичная реализация — конвейер валидации запроса: проверка формата, авторизация, ограничение частоты запросов, бизнес-логика. Любое звено прерывает цепочку отказом, а порядок меняется перестановкой элементов списка.

14. Command

Command упаковывает запрос в объект с данными и методом выполнения. Раз запрос стал объектом, его можно положить в очередь, записать в журнал, повторить или отменить.

Отсюда undo/redo в редакторах, очереди фоновых задач и журналы операций в транзакционных системах. На архитектурном уровне идея превращается в CQRS: команда как объект-намерение изменить состояние отделена от запроса на чтение.

15. Iterator

Iterator даёт последовательный перебор элементов коллекции без раскрытия её внутренней структуры. Клиент работает с методами «следующий» и «есть ли ещё», а под ними может быть массив, дерево или поток данных.

Практические воплощения — курсор базы данных, который тянет строки порциями, и пагинация API, где итератор прячет работу с токеном следующей страницы.

16. Mediator

Mediator убирает прямые связи между компонентами: вместо того чтобы знать друг о друге, они общаются через посредника. Граф связей «каждый с каждым» схлопывается в звезду.

Учебный пример — чат-комната, где участники отправляют сообщения не напрямую, а комнате. Второй пример: диспетчер событий в сложной форме, где изменение одного поля перестраивает остальные.

Архитектурный аналог — Saga с оркестровкой: отдельный координатор вызывает шаги распределённой транзакции и запускает компенсации, а участники друг о друге не знают.

17. Memento

Memento сохраняет снимок внутреннего состояния объекта так, чтобы позже восстановить его, не нарушая инкапсуляцию. Снимок непрозрачен для всех, кроме исходного объекта.

На этом строятся отмена действия, снапшоты документа и контрольные точки в играх и длительных вычислениях. Связка с Command частая: команда хранит снимок состояния до выполнения и использует его при откате.

18. Observer

Паттерн Observer связывает объект-субъект с подписчиками: при изменении состояния субъект уведомляет всех, кто подписался, не зная их конкретных типов.

В коде это event emitter, реактивные потоки и внутренняя шина событий приложения. В распределённых системах та же модель превращается в pub/sub и лежит в основе Event Sourcing, где состояние восстанавливается по журналу событий, и Saga с хореографией, где шаги запускаются реакцией на события соседей.

19. State

State выносит поведение, зависящее от состояния, в отдельные классы: объект делегирует вызовы текущему состоянию и подменяет его при переходе. Вместо ветвления по полю status в каждом методе получается конечный автомат.

Пример — жизненный цикл заказа: новый, оплачен, отправлен, доставлен. Правила «что можно сделать сейчас» живут внутри классов состояний, и добавление статуса «возврат» не требует править десяток условных операторов.

20. Strategy

Strategy описывает семейство взаимозаменяемых алгоритмов с единым интерфейсом, которые выбираются в runtime. Клиент хранит ссылку на стратегию и ничего не знает о её внутренностях.

Примеры: выбор алгоритма сортировки по размеру данных, способ оплаты по стране пользователя, стратегия вытеснения кэша. Отличие от State в намерении: стратегию выбирает внешний код, а состояние переключает себя само по ходу работы.

21. Template Method

Template Method фиксирует скелет алгоритма в базовом классе, оставляя подклассам отдельные шаги. Порядок шагов неизменен, детали подставляются.

Ясный пример — ETL-конвейер: последовательность «извлечь, преобразовать, загрузить» задана, а каждая реализация описывает свои источник и формат. Так же устроены HTTP-клиенты с методами-перехватчиками до и после запроса.

22. Visitor

Visitor добавляет новую операцию к структуре объектов, не меняя их классы: операция выносится в отдельный объект-посетитель, а элементы структуры принимают его и вызывают нужный метод.

Паттерн окупается там, где набор классов стабилен, а набор операций растёт: обход абстрактного синтаксического дерева компилятором или линтером, экспорт одной модели данных в несколько форматов. Обратная сторона: добавление нового типа элемента требует правки всех посетителей.

23. Interpreter

Interpreter описывает грамматику простого языка и способ вычисления выражений: каждому правилу грамматики соответствует класс, а разбор строится как дерево таких объектов.

Применение узкое и конкретное: парсер арифметических или логических выражений, язык фильтров в поисковой строке, шаблонизатор. Для полноценного языка этот подход тяжёл, здесь выигрывают генераторы парсеров.

Часть архитектурных решений повторяет идеи GoF на другом масштабе. Вместо вызова метода работает сетевой запрос, вместо объекта выступает сервис или контейнер, но роль остаётся той же.

GoF-паттернАрхитектурный аналог в микросервисах
FacadeAPI Gateway
ProxyService Mesh (Envoy / Istio)
DecoratorSidecar
AdapterAnti-Corruption Layer
ObserverEvent Sourcing, Saga с хореографией
CommandCQRS (command-часть)
MediatorSaga с оркестровкой
IteratorAPI Composition (перебор ответов сервисов)

У соответствия есть граница. В коде вызов декоратора стоит наносекунды и не падает, а sidecar добавляет сетевой переход, собственное потребление ресурсов и отдельную точку отказа. Аналогия помогает понять замысел, но не заменяет расчёт задержек, повторов и таймаутов. Подробно об архитектурных паттернах — в статье «26 основных паттернов микросервисной разработки».

Частые вопросы про паттерны проектирования GoF

Нужно ли знать все 23 паттерна GoF?

В повседневной работе активно используются 8–10: Singleton, Factory Method, Builder, Adapter, Decorator, Proxy, Observer, Strategy, Command. Остальные полезны для чтения чужого кода и разбора на собеседованиях, но напрямую применяются редко: Interpreter или Flyweight появляются в узких задачах.

Устарели ли паттерны проектирования GoF?

Устарели отдельные реализации, а не концепции. Singleton в сервисах чаще заменяется объектом с единственным экземпляром в DI-контейнере, Strategy в языках с функциями первого класса сводится к передаче функции. При этом популярные фреймворки под капотом построены на тех же шаблонах: фабрики, прокси, наблюдатели и шаблонные методы встречаются в их исходниках постоянно.

Чем паттерны GoF отличаются от архитектурных паттернов?

Уровнем. GoF описывают устройство классов и объектов внутри одного сервиса или модуля, где вызовы локальны и надёжны. Архитектурные паттерны (CQRS, Saga, Circuit Breaker) описывают взаимодействие между сервисами, где есть сеть, задержки и частичные отказы.

Паттерны GoF привязаны к ООП?

Книга описывает их через классы и наследование, но большинство шаблонов переносится в функциональные и мультипарадигменные языки с адаптацией под возможности языка. В Go вместо наследования работают интерфейсы и встраивание, в Python часть паттернов сворачивается до функций и декораторов, в Rust роль Strategy берут трейты и обобщённые типы.

23 паттерна проектирования GoF — не список для заучивания, а словарь, который сокращает обсуждение. Фраза «закроем эту подсистему фасадом» экономит десять минут объяснений, потому что собеседник сразу видит структуру решения. Следующий слой — паттерны микросервисов: многие из них переносят те же идеи на взаимодействие сервисов, добавляя к ним сеть и отказы.

Проверять такие решения удобнее на реальном кластере, чем на схеме. Managed Kubernetes от VK Cloud несёт сертификат Certified Kubernetes — Hosted от CNCF и совместим со стандартным Kubernetes API: манифесты, Helm-чарты и операторы переносятся без переписывания. В кластерах второго поколения системный слой (master-узлы и системные компоненты) размещается в сервисном проекте платформы и обслуживается VK Cloud. Развернуть кластер можно на странице сервиса: Managed Kubernetes от VK Cloud.

Оставьте заявку, чтобы получить консультацию

Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

            Узнавайте о выходе новых статей в блоге первыми!

            Будем держать в курсе новостей и облачных трендов

            section-subscribe_2x.png
              section-subscribe_2x.png
              Теги: паттерны проектирования, GoF, микросервисы, Kubernetes, VK Cloud
              Ссылка скопирована
              Поделиться

              Почитать по теме

              _blog_head_16.png
              28 сентября

              Агентный ИИ в облаке: от function calling до MCP и GPU-инференса

              _blog_head_17.png
              10 сентября

              Open source против закрытого ПО: что на самом деле разделяет две модели разработки

              _blog_head_4.png
              8 сентября

              Что такое ЦОД: устройство, резервирование и метрика PUE

              40+ готовых сервисов