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