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

Что такое паттерн Строитель?

1.2 Junior🔥 111 комментариев
#ООП и паттерны проектирования

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

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

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

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

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

📌 Проблема, которую решает Builder

Представьте класс Product с 10+ полями, где часть полей обязательна, а часть — опциональна. Использование конструктора с множеством параметров становится неудобным:

  • Путаница в порядке аргументов
  • Трудночитаемый код при наличии необязательных параметров
  • Неизменяемость объекта может быть нарушена
  • Телескопические конструкторы (множество перегрузок) усложняют поддержку

🎯 Решение через паттерн Строитель

Паттерн предлагает:

  1. Выделить логику конструирования в отдельный класс Builder
  2. Определить шаги построения через методы Builder
  3. Вернуть готовый продукт после завершения всех шагов

🔧 Ключевые компоненты

// 1. Продукт - сложный объект для создания
public class Pizza
{
    public string Dough { get; set; }
    public string Sauce { get; set; }
    public List<string> Toppings { get; set; } = new();
    public bool CheeseCrust { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"Dough: {Dough}, Sauce: {Sauce}");
        Console.WriteLine($"Toppings: {string.Join(", ", Toppings)}");
        Console.WriteLine($"Cheese crust: {CheeseCrust}");
    }
}

// 2. Интерфейс Строителя
public interface IPizzaBuilder
{
    void SetDough(string dough);
    void SetSauce(string sauce);
    void AddTopping(string topping);
    void SetCheeseCrust(bool enabled);
    Pizza GetPizza();
    void Reset();
}

// 3. Конкретный строитель
public class PizzaBuilder : IPizzaBuilder
{
    private Pizza _pizza = new();
    
    public void Reset() => _pizza = new Pizza();
    
    public void SetDough(string dough) => _pizza.Dough = dough;
    
    public void SetSauce(string sauce) => _pizza.Sauce = sauce;
    
    public void AddTopping(string topping) => _pizza.Toppings.Add(topping);
    
    public void SetCheeseCrust(bool enabled) => _pizza.CheeseCrust = enabled;
    
    public Pizza GetPizza()
    {
        Pizza result = _pizza;
        Reset();
        return result;
    }
}

// 4. Директор (опционально) - управляет процессом построения
public class PizzaDirector
{
    private readonly IPizzaBuilder _builder;
    
    public PizzaDirector(IPizzaBuilder builder) => _builder = builder;
    
    public Pizza MakeMargherita()
    {
        _builder.Reset();
        _builder.SetDough("Thin");
        _builder.SetSauce("Tomato");
        _builder.AddTopping("Mozzarella");
        _builder.AddTopping("Basil");
        return _builder.GetPizza();
    }
}

🚀 Использование паттерна

// Способ 1: Через строитель напрямую
var builder = new PizzaBuilder();
builder.SetDough("Thick");
builder.SetSauce("Cream");
builder.AddTopping("Mushrooms");
builder.AddTopping("Chicken");
builder.SetCheeseCrust(true);
Pizza customPizza = builder.GetPizza();

// Способ 2: Через директор
var director = new PizzaDirector(builder);
Pizza margherita = director.MakeMargherita();

✅ Преимущества паттерна

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

🔄 Fluent Builder (расширенный подход)

public class FluentPizzaBuilder
{
    private readonly Pizza _pizza = new();
    
    public FluentPizzaBuilder WithDough(string dough)
    {
        _pizza.Dough = dough;
        return this;
    }
    
    public FluentPizzaBuilder WithSauce(string sauce)
    {
        _pizza.Sauce = sauce;
        return this;
    }
    
    public Pizza Build() => _pizza;
}

// Использование с цепочкой вызовов
var pizza = new FluentPizzaBuilder()
    .WithDough("Whole Wheat")
    .WithSauce("Pesto")
    .Build();

🎭 Отличия от других паттернов

  • Vs Factory Method: Factory создает объекты в одном шаге, Builder — пошагово
  • Vs Abstract Factory: Abstract Factory создает семейства объектов, Builder фокусируется на одном сложном объекте
  • Vs Prototype: Prototype клонирует существующий объект, Builder конструирует с нуля

💼 Практическое применение в C#

  • Построение SQL-запросов (QueryBuilder)
  • Конфигурация объектов (HttpClientBuilder в ASP.NET Core)
  • Создание документов (HTML, XML генераторы)
  • Инициализация DTO с множеством опциональных полей

Паттерн Строитель особенно полезен в C# Backend разработке для создания конфигурационных объектов, сложных моделей данных и построителей запросов, обеспечивая чистый, поддерживаемый и расширяемый код.

Что такое паттерн Строитель? | PrepBro