Маленькая шпаргалка для тех кто хочет понять что это и как называется. Изначальная цель написания - предоставить заинтересованным лицам краткую справку и возможность более эффективно воспользоваться поисковыми системами. Здесь перечислены как классические паттерны и антипаттерны проектирования от банды четырёх (GoF), так и прочие общепринятые.

Паттерны

группа

тип

цель

описание

Creational

Abstract Factory

Генерализация процесса создания и инициализации объектов

Позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам. Например, фабрика для создания элементов интерфейса под Windows или macOS

Builder

Композиция комплексных алгоритмов инициализации

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

Factory Method

Генерализация создания объектов разных типов

Определяет общий интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемого объекта. Например, метод createLogger() может вернуть FileLogger или EmailLogger

Prototype

Экономия ресурсов на создание объекта

Создаёт новые объекты путём клонирования существующего экземпляра (прототипа). Это удобно, когда создание объекта «с нуля» дороже копирования

Singleton

Абстракция и инкапсуляция глобального состояния в класс

Гарантирует, что у класса есть ��олько один экземпляр, и предоставляет к нему глобальную точку доступа. Например, класс для работы с базой данных или конфигурацией приложения

Structural

Adapter

Клей. композиция несовместимых интерфейсов

Позволяет объектам с несовместимыми интерфейсами работать вместе. Как переходник с европейской розетки на американскую

Bridge

Абстрагирование интерфейса от реализации

Разделяет абстракцию и реализацию так, чтобы они могли изменяться независимо. Например, отделяем геометрические фигуры (круг, квадрат) от способа их отрисовки (растровая, векторная графика)

Composite

Компоновка объектов

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

Decorator

"микро-расширение" обсновы

Динамически добавляет объекту новую функциональность, оборачивая его в полезные «обёртки». Например, можно обернуть базовое уведомление в декоратор SMS или декоратор Slack

Facade

симплификация интерфейса к сложной системе

Предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку

Flyweight

Экономия ОЗУ на объектах с общим состоянием

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

Proxy

Делегирование доступа к объекту/его состоянию

Подставляет объект-заменитель, который управляет доступом к другому объекту. Может использоваться для ленивой загрузки, контроля доступа, логирования

Behavioral

Chain of Responsibility

Каскадирование обработки

Позволяет передавать запросы последовательно по цепочке обработчиков. Каждый обработчик решает, может ли он обработать запрос, и если нет — передаёт дальше

Command

действие-как-объект

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

Iterator

Абстракция последовательного итерирования по объекту

Даёт способ последовательно обходить элементы составного объекта, не раскрывая его внутреннего устройства

Mediator

Уменьшение связности объектов

Уменьшает связанность множества объектов, заставляя их общаться не друг с другом напрямую, а через объект-посредник. Как авиадиспетчер для самолётов

Memento

Откат изменений

Позволяет сохранять и восстанавливать предыдущее состояние объекта, не раскрывая подробностей его реализации. Механизм отмены действий (undo)

Observer

Событийность

Создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах. Основа событийно-ориентированного программирования

State

Несколько моделей поведения в одном объекте

Позволяет объекту менять своё поведение в зависимости от внутреннего состояния. Создаётся впечатление, что объект сменил класс

Strategy

Инкапсуляция алгоритма от поставленной задачи

Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Например, выбор способа сортировки массива (пузырьком, быстрая сортировка)

Template Method

Скелет алгоритма с перегружаемыми частями

Определяет скелет алгоритма в методе, оставляя некоторые шаги подклассам. Подклассы могут переопределять эти шаги, не меняя структуру алгоритма

Visitor

Расширение набора операций без изменения класса

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

Architectural

Layered

Каскадное слоение

Система делится на горизонтальные уровни (слои), каждый из которых выполняет определённую функцию. Каждый слой знает только о нижележащем. Это упрощает разработку и тестирование

Model-View-Controller

разделение ответственности через посредника

MVC разделяет ответственность, упрощает поддержку и позволяет тестировать логику отдельно от интерфейса. Делится на три состовляющие: модель, представление и контроллер (посредник)

Model-View-Presenter

разделение ответственности через посредника

Вариант MVC, где Presenter заменяет контроллер. Presenter содержит логику представления и управляет моделью, а View только отображает данные и передаёт действия пользователя презентеру. Часто используется в Android и веб-формах

Microservices

повышение гибкости масштабирования и независимости развёртывания

Приложение строится как набор небольших независимых сервисов, каждый из которых реализует определённую бизнес-способность. Сервисы общаются по сети (REST, gRPC, очередь сообщений). Это даёт гибкость масштабирования и независимость развёртывания, но усложняет управление распределённой системой

Event-Driven

Обеспечение слабой связанности и высокой масштабируемости

Компоненты системы реагируют на события, генерируемые другими компонентами. События передаются через шину событий или брокер (Kafka, RabbitMQ)

Repository

сокрытие деталей доступа к данным за единым интерфейсом

Приложения работают с коллекцией объектов (репозиторием) как с обычной коллекцией в памяти, не зная, откуда берутся данные (БД, API, файл). Часто сочетается с Data Mapper (например, в Doctrine, Hibernate)

Command Query Responsibility Segregation

оптимизация чтения и записи отдельно, масштабирование обоих по-разному

Разделение операций записи (команды) и чтения (запросы) на разные модели. Команды меняют состояние, запросы только читают. Часто идёт в паре с Event Sourcing.

Event Sourcing

полный аудит, возможность "откатиться" к любому моменту

Вместо хранения текущего состояния сохраняется вся последовательность событий, которые привели к этому состоянию. Текущее состояние восстанавливается повторным применением событий

Enterprise Service Bus

интеграция сервисов

Центральный компонент, который интегрирует различные приложения, маршрутизируя сообщения и преобразуя протоколы. Часто используется в корпоративных системах (SOA)

Concurrency

Thread Pool

Экономия ресурсов на создание/уничтожение потоков и предотвращение перегрузки системы

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

Active Object

вызов метода асинхронно без явного управления потоками

Разделяет вызов метода и его выполнение. Вызов метода возвращает «будущее» (future) или обещание (promise), а реальная работа выполняется в отдельном потоке

Monitor Object

Упрощение написания потокобезопасного кода

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

Double-Checked Locking

отложенная инициализация в многопоточной среде

Сначала проверяется, создан ли объект (без синхронизации), и если нет, то выполняется синхронизированный блок для создания

Producer-Consumer

Разделение постановки и обработки, сглаживание пиковых нагрузкок

Один или несколько потоков (производителей) генерируют данные и помещают их в общую очередь, а другие потоки (потребители) забирают данные и обрабатывают

Readers-Writers

Увеличение параллелизма по сравнению с простым монитором

Позволяет одновременное чтение данных многими потоками, но запись требует исключительного доступа

Immutable Object

свободное разделение объекта между потоками без синхронизации

Объект, состояние которого не может быть изменено после создания. Такие объекты потокобезопасны по определению

Balking

снижение количества исключительных состояний

Если объект находится в неподходящем состоянии для выполнения запрошенной операции, операция просто не выполняется (игнорируется) или возвращает ошибку. Например, попытка закрыть уже закрытый файл

Scheduler

Явное управление тем, какой поток когда выполняется

Может реализовывать политики: Round Robin, приоритетное планирование и т.д. Часто скрыт внутри пулов потоков, но в реальном времени может быть реализован явно

Half-Sync / Half-Async

Упрощение проектирования серверов

Разделяет систему на два уровня: асинхронный (обработка событий ввода-вывода) и синхронный (бизнес-логика). Между ними располагается очередь, которая буферизует данные

Leader / Followers

Избавление от накладных расходов на передачу события между потоками

Несколько потоков ждут событий. Один поток назначается лидером и ждёт событие на общем дескрипторе. Когда событие происходит, лидер просыпается, назначает нового лидера из числа последователей, а сам обрабатывает событие

Антипаттерны

группа

тип

описание

решение

Code & Design

God Object

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

Разделить ответственность на несколько небольших классов (принцип единственной ответственности)

Copy-Paste

Многократное копирование одного и того же кода вместо вынесения его в общую функцию или класс. Приводит к дублированию логики — ошибку приходится править во многих местах

DRY (Don’t Repeat Yourself) — выделяйте повторяющийся код в отдельные модули

Spaghetti Code

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

Рефакторинг, выделение методов, следование принципам структурного и объектно-ориентированного программирования

Golden Hammer

Использование одной и той же технологии, паттерна или подхода для всех задач, даже когда они не подходят. Например, повсюду применять Singleton или делать всё через веб-сервисы

Оценивать требования задачи и выбирать инструмент соответственно

Dead Code

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

Регулярно чистить код, удалять неиспользуемые части

Premature Optimization

Попытки оптимизировать производительность на ранних этапах, когда ещё неизвестны узкие места. Это часто усложняет код и не даёт реального выигрыша

Сначала пишите понятный и правильный код, затем профилируйте и оптимизируйте только проблемные участки

Magic Numbers

Использование числовых значений напрямую в коде без пояснений (например, if (status == 2)). Это делает код непонятным и сложным в поддержке

Заменять константами с осмысленными именами

Constructor Over-injection

Конструктор класса принимает слишком много параметров, что говорит о том, что класс делает слишком много

Разбить класс на несколько; использовать паттерны Builder или Factory

Telepathy

Класс неявно зависит от деталей реализации другого класса (например, знает о том, какие поля у того есть и как они используются). Приводит к сильной связанности

Явно передавать зависимости через интерфейсы или параметры

Architectural

Big Ball of Mud

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

Провести рефакторинг, внедрить слои, модули и чёткие интерфейсы

Boat Anchor

Часть системы или компонент, который разработан и включён в проект, но реально не используется, однако от него трудно отказаться (потому что уже вложены ресурсы)

Смело удалять, если функциональность не востребована

Ambient Bridge

Использование сложной интеграционной шины (ESB) для простейших взаимодействий, что добавляет ненужную сложность

Применять более лёгкие механизмы связи (прямые вызовы, очереди), если нет реальной потребности в ESB

Stovepipe System

Система состоит из изолированных компонентов («дымоходов»), которые не обмениваются данными или делают это через сложные «стыки». Данные дублируются, бизнес-процессы нарушаются

Интегрировать компоненты через общие интерфейсы и данные; использовать сервисную шину или общее хранилище

Analysis Paralysis

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

Итеративный подход — проектировать и сразу реализовывать малыми шагами

Vendor Lock-In

Сильная привязка к конкретному проприетарному продукту, API или облачному сервису. При смене вендора переделывать всё приложение

Использовать абстракции и стандартизированные интерфейсы, чтобы можно было заменить реализацию

Distributed Monolith

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

Декомпозировать по бизнес-способностям, обеспечить независимость данных и использовать асинхронность

Organization

Hero Culture

Один разработчик (или небольшая группа) постоянно «спасает» проект, работая сверхурочно, исправляя чужие ошибки. Остальные расслабляются, а герой выгорает

Распределять знания, улучшать процессы, автоматизировать, не поощрять подвиги ценой здоровья

Carrot and Stick

Мотивация только поощрениями и наказаниями без учёта внутренней мотивации. Приводит к формальному выполнению задач, отсутствию инициативы

Создавать условия для самореализации, давать автономию, признавать вклад

Bureaucratic Sabotage

Чрезмерные согласования, отчёты, регламенты, которые тормозят разработку и демотивируют команду

Оптимизировать процессы, оставлять только необходимые процедуры

Death March

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

Честно оценивать риски, говорить о проблемах на ранних этапах, отказываться от невыполнимых обязательств

Armchair Architecture

Архитектура создаётся людьми, далёкими от реальной разработки (например, консультантами, не погружёнными в контекст), и не учитывает технические ограничения и потребности команды

Вовлекать в проектирование тех, кто будет писать код

Second-System Effect

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

Строго ограничивать функциональность, сохранять простоту