Маленькая шпаргалка для тех кто хочет понять что это и как называется. Изначальная цель написания - предоставить заинтересованным лицам краткую справку и возможность более эффективно воспользоваться поисковыми системами. Здесь перечислены как классические паттерны и антипаттерны проектирования от банды четырёх (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 |
Использование числовых значений напрямую в коде без пояснений (например, |
Заменять константами с осмысленными именами |
|
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 |
При разработке новой версии системы разработчики добавляют все функции, которые не успели в первую версию, делая систему перегруженной и сложной |
Строго ограничивать функциональность, сохранять простоту |