Что такое паттерн Строитель?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
🏗️ Паттерн Строитель (Builder)
Паттерн Строитель — это порождающий шаблон проектирования, который позволяет создавать сложные объекты пошагово, отделяя процесс конструирования от его представления. Основная цель — упростить создание объектов с большим количеством параметров, особенно когда некоторые из них являются необязательными или требуют сложной логики инициализации.
📌 Проблема, которую решает Builder
Представьте класс Product с 10+ полями, где часть полей обязательна, а часть — опциональна. Использование конструктора с множеством параметров становится неудобным:
- Путаница в порядке аргументов
- Трудночитаемый код при наличии необязательных параметров
- Неизменяемость объекта может быть нарушена
- Телескопические конструкторы (множество перегрузок) усложняют поддержку
🎯 Решение через паттерн Строитель
Паттерн предлагает:
- Выделить логику конструирования в отдельный класс
Builder - Определить шаги построения через методы
Builder - Вернуть готовый продукт после завершения всех шагов
🔧 Ключевые компоненты
// 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 разработке для создания конфигурационных объектов, сложных моделей данных и построителей запросов, обеспечивая чистый, поддерживаемый и расширяемый код.