Порождающие паттерны

Порождающие паттерны изолируют решение что, когда и с какими параметрами создать. Они полезны, когда прямой 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.

Вопросы для повторения

  1. Где находится решение о конкретном типе?
  2. Кто владеет жизненным циклом созданного объекта?
  3. Можно ли получить объект с нарушенным инвариантом?
  4. Как добавить новый вариант и какие существующие классы изменятся?
  5. Что проще подменить в тесте?

Навигация: Шаблоны проектирования, Паттерны, Принципы SOLID.