O problema de muitos parâmetros

Uma requisição de relatório pode ter formato, intervalo, filtros, ordenação e opções opcionais. Um construtor com oito argumentos booleanos não mostra o significado de cada valor; setters públicos podem deixar o objeto incompleto. Builder oferece métodos nomeados para compor a configuração e um ponto para validar o resultado.

Exemplo em C#

public sealed record RelatorioOptions(
    DateOnly Inicio, DateOnly Fim, bool IncluirCancelados);

public sealed class RelatorioOptionsBuilder
{
    private DateOnly? _inicio;
    private DateOnly? _fim;
    private bool _incluirCancelados;

    public RelatorioOptionsBuilder NoPeriodo(DateOnly inicio, DateOnly fim)
    {
        _inicio = inicio;
        _fim = fim;
        return this;
    }

    public RelatorioOptionsBuilder IncluirCancelados()
    {
        _incluirCancelados = true;
        return this;
    }

    public RelatorioOptions Build()
    {
        if (_inicio is null || _fim is null || _inicio > _fim)
            throw new InvalidOperationException("Período inválido.");
        return new(_inicio.Value, _fim.Value, _incluirCancelados);
    }
}

O objeto final pode ser imutável. A validação em Build evita que a configuração parcialmente preenchida escape. Para tipos menores, um record com parâmetros nomeados pode ser mais simples e igualmente seguro.

Quando usar e quando evitar

Use quando há muitos parâmetros opcionais, etapas de construção, validações cruzadas ou várias representações do mesmo processo. Evite para objetos pequenos com poucos valores obrigatórios. Builder também pode esconder excesso de opções: se combinações são difíceis de validar, talvez o modelo precise de tipos menores ou de conceitos separados.

Relacionado

Factory Method escolhe qual produto criar; Builder se concentra em como completar sua construção. Prototype cria por cópia. Consulte o guia de Design Patterns e os princípios SOLID.