Builder

Construye objetos complejos paso a paso, separando el algoritmo de construcción de su representación.

Contexto

Una clase tiene 12 parámetros opcionales (timeouts, headers, retries, proxy…). Su constructor es ilegible y nunca recuerdas el orden.

Problema
  • Constructores telescópicos imposibles de leer.
  • Necesidad de validar el objeto antes de instanciarlo.
Solución

Un Builder acumula configuración con métodos encadenables y, al final, Build() valida y produce el objeto inmutable.

#Ejemplo en C# — Fluent Builder

public sealed class HttpClientOptions
{
    public Uri BaseAddress { get; init; } = default!;
    public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(30);
    public IReadOnlyDictionary<string, string> Headers { get; init; } = new Dictionary<string, string>();
}

public class HttpClientOptionsBuilder
{
    private Uri? _base;
    private TimeSpan _timeout = TimeSpan.FromSeconds(30);
    private readonly Dictionary<string, string> _headers = new();

    public HttpClientOptionsBuilder BaseAddress(string url) { _base = new Uri(url); return this; }
    public HttpClientOptionsBuilder Timeout(TimeSpan t)     { _timeout = t; return this; }
    public HttpClientOptionsBuilder Header(string k, string v) { _headers[k] = v; return this; }

    public HttpClientOptions Build()
    {
        if (_base is null) throw new InvalidOperationException("BaseAddress requerido");
        return new HttpClientOptions { BaseAddress = _base, Timeout = _timeout, Headers = _headers };
    }
}

// Uso
var opts = new HttpClientOptionsBuilder()
    .BaseAddress("https://api.example.com")
    .Timeout(TimeSpan.FromSeconds(10))
    .Header("X-Api-Key", "secret")
    .Build();
Cuándo NO aplicarlo
  • Cuando el objeto tiene 2-3 parámetros: usa el constructor o un record.
  • Cuando los datos vienen de un DTO/JSON: deserializa directamente.
Tradeoffs
Pro Contra
Lectura tipo prosa Más código boilerplate
Validación centralizada Estado mutable temporal en el builder
Permite construir variantes con el mismo API Refactorizar el objeto obliga a sincronizar el builder

#Variantes

  • Director clásico GoF (orquesta builders).
  • Step Builder (cada paso devuelve una interfaz distinta forzando el orden).

#creational #gof #fluent