Порождающие паттерны
Порождающие паттерны изолируют решение что, когда и с какими параметрами создать.
Они полезны, когда прямой new заставляет клиент знать слишком много.
Карта выбора
| Ситуация | Паттерн | Откуда берётся конфигурация |
|---|---|---|
| Много параметров и обязательная валидация | Строитель Builder | Из цепочки именованных шагов |
| Общий алгоритм оставляет выбор типа подклассу | Фабричный метод Factory Method | Из переопределённого метода |
| Нужен согласованный набор реализаций | Абстрактная фабрика Abstract Factory | Из выбранного семейства |
| Нужен вариант уже настроенного объекта | Прототип Prototype | Из состояния образца |
| В системе допустим ровно один управляемый экземпляр | Одиночка Singleton | Из глобального жизненного цикла |
Как различать на собеседовании
Builder и Abstract Factory
Builder обычно выдаёт один результат после серии настроек. Abstract Factory сразу предоставляет методы создания нескольких связанных продуктов.
Factory Method и Abstract Factory
Factory Method — одна полиморфная точка создания в иерархии creator-классов. Abstract Factory — объект с набором операций; семейство меняется композицией.
Prototype и Builder
Prototype начинает с существующего состояния. Builder явно накапливает параметры. Для Prototype главный вопрос — глубина копирования, для Builder — полнота и валидация сборки.
Проверка необходимости
Перед добавлением паттерна проверить простые варианты:
- обычный конструктор для небольшого неизменяемого объекта;
- статическая фабрика для именованного способа создания;
Supplier<T>для передачи функции создания;- DI-конфигурация для выбора реализации;
- record для компактного объекта-значения.
Типичные ошибки
- Builder с сеттерами, который позволяет получить незавершённый продукт;
- Factory Method, фактически являющийся большим
switchбез полиморфизма; - Abstract Factory с несвязанными продуктами;
- Prototype с неявно разделяемыми изменяемыми коллекциями;
- Singleton как скрытый глобальный mutable state.
Вопросы для повторения
- Где находится решение о конкретном типе?
- Кто владеет жизненным циклом созданного объекта?
- Можно ли получить объект с нарушенным инвариантом?
- Как добавить новый вариант и какие существующие классы изменятся?
- Что проще подменить в тесте?
Навигация: Шаблоны проектирования, Паттерны, Принципы SOLID.