В чем разница фабрики и билдера
Что проверяют
Различаете ли вы две разные задачи: выбрать, какой тип создать, и собрать один сложный объект по частям. Следом часто спрашивают, нужен ли вообще Builder в Swift, где есть параметры по умолчанию.
Как отвечать
Коротко: фабрика отвечает на вопрос «что создать», строитель на вопрос «как собрать».
- Фабрика: прячет выбор конкретного типа. Клиент получает протокол и не знает, какой класс за ним стоит. Стоит разделить простую фабрику (статический метод
make(...)), фабричный метод из GoF, где решение принимает подкласс, и абстрактную фабрику, которая выпускает семейство связанных объектов, например набор компонентов под две темы оформления. В iOS фабрики постоянно собирают экраны:ModuleFactoryсоздаётUIViewControllerвместе с презентером и зависимостями, а координатор вызывает её, ничего не зная о внутренностях; - Строитель: пошагово настраивает один тип с множеством необязательных частей и проверяет целостность в финальном
build(). Удобен, когда шаги зависят от порядка или конфигурация копится в разных местах кода.
В Swift строитель нужен реже, чем в Java: инициализатор с параметрами по умолчанию и memberwise-инициализатор структуры закрывают большинство случаев. Он оправдан для сборки URLRequest с заголовками, телом и авторизацией, для NSAttributedString из кусков, для конфигураций, которые передаются по цепочке. Хороший строитель это структура с методами, возвращающими изменённую копию, и build() throws, который отказывается собрать неполный объект.
Можно упомянуть @resultBuilder: на нём построен SwiftUI, но это механизм языка для DSL, а не классический GoF-строитель, хотя название общее.
Где спотыкаются
Пишут фабрику со switch по строке и опциональным результатом. Опечатка в строке превращается в nil во время работы, а enum дал бы проверку компилятором.
Делают строитель классом, который меняет один и тот же объект и возвращает на него ссылку из build(). Повторный вызов сеттера после сборки меняет уже выданный объект.
Называют «фабричным методом» любую функцию, которая возвращает новый объект, и не могут объяснить, чем он отличается от абстрактной фабрики.