Abstract Factory и Builder
Два порождающих паттерна для непростого создания: семейства связанных объектов (Abstract Factory) и пошаговая сборка (Builder).
Abstract Factory создаёт семейства связанных объектов, а Builder пошагово собирает один сложный объект, отделяя конструирование от представления.
Abstract Factory: согласованные семейства
Представьте UI-тему. Светлая и тёмная темы должны давать согласованный набор: тёмная кнопка с тёмным чекбоксом, а не вперемешку. Abstract Factory — это фабрика, которая отдаёт целое семейство объектов одного «стиля», гарантируя их совместимость.
from abc import ABC, abstractmethod
class Button(ABC):
@abstractmethod
def render(self): ...
class DarkButton(Button):
def render(self): return "тёмная кнопка"
class LightButton(Button):
def render(self): return "светлая кнопка"
class Theme(ABC): # абстрактная фабрика
@abstractmethod
def button(self) -> Button: ...
class DarkTheme(Theme):
def button(self): return DarkButton()
class LightTheme(Theme):
def button(self): return LightButton()
def build_ui(theme: Theme):
print(theme.button().render())
build_ui(DarkTheme())
build_ui(LightTheme())
Вывод:
тёмная кнопка светлая кнопка
Каждая конкретная фабрика (DarkTheme, LightTheme) производит свой набор продуктов. Клиент выбирает фабрику один раз — и дальше получает гарантированно согласованные элементы. Реальные продукты обычно имеют несколько методов (кнопка, чекбокс, поле ввода).
Builder: пошаговая сборка
Когда у объекта много опциональных частей, конструктор с десятью аргументами становится нечитаемым. Builder задаёт сборку по шагам и в конце отдаёт готовый объект. Удобно делать методы «текучими» (возвращать self).
class Burger:
def __init__(self):
self.parts = []
class BurgerBuilder:
def __init__(self):
self._burger = Burger()
def add(self, part):
self._burger.parts.append(part)
return self # текучий интерфейс
def build(self):
return self._burger
burger = (BurgerBuilder()
.add("булка")
.add("котлета")
.add("сыр")
.build())
print(" + ".join(burger.parts))
Вывод:
булка + котлета + сыр
Чтение сборки идёт сверху вниз как рецепт. Builder особенно хорош, когда часть шагов опциональна или порядок важен (например, конфигурация HTTP-запроса, построение SQL).
Когда что выбрать
- Abstract Factory — когда нужно создавать несколько видов объектов, которые должны быть согласованы между собой.
- Builder — когда один объект сложный и собирается из многих опциональных частей.
Где встречается
Abstract Factory — кросс-платформенные UI-наборы, драйверы под разные СУБД. Builder — построители запросов (query builders), StringBuilder, конфигурации тестовых объектов, сборка сложных DTO.
Итог
- Abstract Factory отдаёт согласованное семейство объектов.
- Builder собирает один сложный объект пошагово, часто с текучим интерфейсом.
- Оба отделяют клиента от деталей конструирования.