Padrão Builder com API Fluente
Construa objetos complexos passo a passo com um builder fluente para evitar construtores telescópicos.
Padrão Builder com API Fluente é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O problema do construtor telescópico
Quando uma classe tem muitos parâmetros opcionais, os construtores se multiplicam: 2 parâmetros, 3 parâmetros, 4 parâmetros... O Builder resolve isso com uma API de configuração fluente e passo a passo.
// Without builder — hard to read:
Pizza p = new Pizza("large", "thin", true, false, true, false, "mozzarella");Estrutura básica de Builder
Crie uma classe Builder aninhada estática. A classe externa tem um construtor privado que aceita o builder. Cada método configurador do builder retorna this para permitir encadeamento fluente.
public final class Pizza {
private final String size, crustType, cheese;
private final boolean extraSauce, pepperoni;
private Pizza(Builder b) {
this.size = b.size; this.crustType = b.crustType;
this.cheese = b.cheese; this.extraSauce = b.extraSauce;
this.pepperoni = b.pepperoni;
}
public static class Builder {
private final String size;
private String crustType = "regular", cheese = "mozzarella";
private boolean extraSauce, pepperoni;
public Builder(String size) { this.size = size; }
public Builder crustType(String c) { this.crustType = c; return this; }
public Builder cheese(String c) { this.cheese = c; return this; }
public Builder extraSauce() { this.extraSauce = true; return this; }
public Builder pepperoni() { this.pepperoni = true; return this; }
public Pizza build() { return new Pizza(this); }
}
}Uso da API fluente
O builder é lido como uma frase. Os parâmetros obrigatórios vão no construtor; os opcionais são chamadas de método. A chamada final de build() produz o objeto imutável.
Pizza p = new Pizza.Builder("large")
.crustType("thin")
.extraSauce()
.pepperoni()
.build();
System.out.println(p);Validação em build()
Adicione a lógica de validação dentro de build() antes de construir o objeto. Lance IllegalStateException ou IllegalArgumentException para combinações inválidas.
public Pizza build() {
if (size == null || size.isBlank())
throw new IllegalArgumentException("Size required");
if (extraSauce && crustType.equals("stuffed"))
throw new IllegalStateException("No extra sauce on stuffed crust");
return new Pizza(this);
}Builder para objetos imutáveis
Como a classe externa é criada de uma só vez a partir do builder, todos os campos podem ser final, tornando o objeto resultante completamente imutável e seguro para execução concorrente.
public final class Address {
private final String street, city, country;
private final String postalCode;
private Address(Builder b) { ... } // all finals
// no setters — immutable!
}Builder genérico com tipo próprio
Para hierarquias de herança, utilize um parâmetro de tipo genérico recursivo (SELF extends Builder<SELF>) para que os builders das subclasses retornem o tipo da subclasse nos métodos encadeados.
public abstract static class Builder<SELF extends Builder<SELF>> {
String name;
@SuppressWarnings("unchecked")
public SELF name(String n) { this.name = n; return (SELF) this; }
public abstract Vehicle build();
}Lombok @Builder
O Lombok gera toda a infraestrutura do builder durante a compilação por meio de @Builder. Utilize @Builder.Default para valores padrão dos campos e @Singular para coleções.
@Builder
public class Report {
private final String title;
@Builder.Default private final int pageCount = 1;
@Singular private final List<String> authors;
}
// Usage:
Report r = Report.builder().title("Q4").author("Alice").author("Bob").build();Builder no JDK
Muitas classes do JDK utilizam APIs no estilo builder: StringBuilder, HttpRequest.newBuilder(), ProcessBuilder, Stream.Builder. Reconheça o padrão.
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Accept", "application/json")
.GET()
.build();Builder versus fábrica
Utilize Builder quando um objeto exigir muitos parâmetros e configuração passo a passo. Utilize uma fábrica quando todas as variantes forem simples e a criação puder ser feita em uma única chamada.
Builder para dados de teste
Builders são excelentes em testes: crie um builder base em um auxiliar e depois substitua apenas os campos relevantes para cada caso de teste, mantendo os testes DRY e legíveis.
User defaultUser() { return new User.Builder("test@example.com").name("Test User").build(); }
User adminUser() { return new User.Builder("admin@example.com").name("Admin").role(ADMIN).build(); }Segurança em execução concorrente
O builder em si não é seguro para execução concorrente — não compartilhe um Builder entre fluxos de execução. O produto construído a partir dele pode ser imutável e seguro para execução concorrente se todos os campos forem finais e nenhum objeto mutável for compartilhado.
Verificação rápida
O que torna um método do builder "fluente"?
Recapitulação
O Builder resolve o problema do construtor telescópico. Utilize uma classe Builder aninhada estática, retorne this de cada método configurador, valide em build() e produza um objeto imutável. O Lombok @Builder automatiza o código repetitivo.
Perguntas Frequentes
A aula “Padrão Builder com API Fluente” é grátis?
Sim — o texto completo de “Padrão Builder com API Fluente” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Padrão Builder com API Fluente”?
Construa objetos complexos passo a passo com um builder fluente para evitar construtores telescópicos. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Padrão Builder com API Fluente”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Singleton: Implementações Seguras para Threads
- Padrão Factory Method
- Abstract Factory para Famílias de Produtos
- Padrão Builder com API Fluente