← Назад к вопросам

Что такое шаблон Builder?

3.0 Senior🔥 301 комментариев
#REST API и HTTP#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Паттерн Builder (Строитель)

Builder — это порождающий паттерн проектирования, который используется для пошагового создания сложных объектов. Он отделяет процесс конструирования объекта от его представления, позволяя создавать различные варианты объекта.

Основная идея

Вместо передачи множества параметров в конструктор, мы создаём промежуточный объект (Builder), который накапливает значения параметров и затем создаёт целевой объект с помощью метода build().

Когда использовать Builder

  • Много параметров в конструкторе (более 3-4)
  • Много опциональных параметров
  • Разные комбинации параметров нужны в разных местах
  • Создание иммутабельных объектов
  • Пошаговое конструирование объекта

Пример с классом и Builder

class House:
    def __init__(self, wall_type: str, roof_type: str, has_garage: bool, 
                 windows_count: int, doors_count: int):
        self.wall_type = wall_type
        self.roof_type = roof_type
        self.has_garage = has_garage
        self.windows_count = windows_count
        self.doors_count = doors_count

    def __repr__(self):
        return (f"House(wall={self.wall_type}, roof={self.roof_type}, "
                f"garage={self.has_garage}, windows={self.windows_count})")

class HouseBuilder:
    def __init__(self):
        self.wall_type = "wood"
        self.roof_type = "tile"
        self.has_garage = False
        self.windows_count = 4
        self.doors_count = 2

    def set_walls(self, wall_type: str) -> "HouseBuilder":
        self.wall_type = wall_type
        return self  # Возвращаем self для цепочки вызовов

    def set_roof(self, roof_type: str) -> "HouseBuilder":
        self.roof_type = roof_type
        return self

    def set_garage(self, has_garage: bool) -> "HouseBuilder":
        self.has_garage = has_garage
        return self

    def set_windows(self, count: int) -> "HouseBuilder":
        self.windows_count = count
        return self

    def set_doors(self, count: int) -> "HouseBuilder":
        self.doors_count = count
        return self

    def build(self) -> House:
        return House(
            wall_type=self.wall_type,
            roof_type=self.roof_type,
            has_garage=self.has_garage,
            windows_count=self.windows_count,
            doors_count=self.doors_count
        )

# Использование
builder = HouseBuilder()
house1 = (builder
    .set_walls("brick")
    .set_roof("metal")
    .set_garage(True)
    .set_windows(8)
    .build())

print(house1)  # House(wall=brick, roof=metal, garage=True, windows=8)

Встроенный Builder в dataclass

В Python можно использовать dataclass с параметрами, что является лёгким вариантом Builder:

from dataclasses import dataclass
from typing import Optional

@dataclass
class DatabaseConfig:
    host: str
    port: int = 5432
    username: str = "admin"
    password: Optional[str] = None
    timeout: int = 30
    ssl_enabled: bool = False

# Использование — просто передаём нужные параметры
config = DatabaseConfig(
    host="localhost",
    ssl_enabled=True,
    timeout=60
)

Плюсы паттерна

  • Читаемость кода — ясно видны все параметры
  • Гибкость — легко менять комбинации параметров
  • Безопасность — можно проверить валидность в методе build()
  • Цепочка вызовов — удобный и выразительный синтаксис

Минусы паттерна

  • Больше кода — требует дополнительного класса
  • Производительность — создание дополнительного объекта
  • Избыточность — для простых объектов можно обойтись без паттерна

Builder часто используется в реальных проектах, например в ORM (SQLAlchemy query builder), HTTP-клиентах и конфигурационных системах.