Patrón Builder con API fluida
Construya objetos complejos paso a paso con un builder fluido para evitar constructores telescópicos.
Patrón Builder con API fluida es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
El problema de los constructores telescópicos
Cuando una clase tiene muchos parámetros opcionales, los constructores se multiplican: de 2 parámetros, de 3, de 4... El patrón Builder resuelve este problema con una API fluida de configuración paso a paso.
// Without builder — hard to read:
Pizza p = new Pizza("large", "thin", true, false, true, false, "mozzarella");Estructura básica de Builder
Cree una clase Builder anidada estática. La clase externa tiene un constructor privado que acepta el builder. Cada método setter del builder devuelve this para permitir el encadenamiento fluido.
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 de una API fluida
El builder se lee como una oración. Los parámetros obligatorios se incluyen en el constructor; los opcionales se establecen mediante llamadas a métodos. La llamada final a build() produce el objeto inmutable.
Pizza p = new Pizza.Builder("large")
.crustType("thin")
.extraSauce()
.pepperoni()
.build();
System.out.println(p);Validación en build()
Añada la lógica de validación dentro de build() antes de construir el objeto. Lance IllegalStateException o IllegalArgumentException para las combinaciones no vá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 inmutables
Como la clase externa se crea a partir del builder de una sola vez, todos los campos pueden ser final, lo que hace que el objeto resultante sea completamente inmutable y seguro para hilos.
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 con tipo propio
Para jerarquías de herencia, utilice un parámetro de tipo genérico recursivo (SELF extends Builder<SELF>) para que los builders de las subclases devuelvan el tipo de la subclase al encadenar métodos.
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
@Builder de Lombok genera toda la infraestructura del builder durante la compilación. Utilice @Builder.Default para los valores predeterminados de los campos y @Singular para las colecciones.
@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 en el JDK
Muchas clases del JDK utilizan API con estilo builder: StringBuilder, HttpRequest.newBuilder(), ProcessBuilder y Stream.Builder. Aprenda a reconocer el patrón.
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Accept", "application/json")
.GET()
.build();Builder frente a Factory
Utilice Builder cuando un objeto requiera muchos parámetros y una configuración paso a paso. Utilice Factory cuando todas las variantes sean sencillas y la creación pueda realizarse en una sola llamada.
Builder para datos de prueba
Los builders son especialmente útiles en las pruebas: cree un builder base en una clase auxiliar y sobrescriba después solo los campos relevantes para cada caso de prueba, manteniendo las pruebas DRY y legibles.
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(); }Seguridad de hilos
El builder no es seguro para hilos; no comparta un Builder entre varios hilos. El producto construido a partir de él puede ser inmutable y seguro para hilos si todos los campos son final y no se comparten objetos mutables.
Comprobación rápida
¿Qué hace que un método de builder sea «fluido»?
Resumen
Builder resuelve el problema de los constructores telescópicos. Utilice una clase Builder anidada estática, devuelva this desde cada setter, valide en build() y produzca un objeto inmutable. Lombok @Builder automatiza el código repetitivo.
Preguntas frecuentes
¿La lección «Patrón Builder con API fluida» es gratis?
Sí — el texto completo de «Patrón Builder con API fluida» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Patrón Builder con API fluida»?
Construya objetos complejos paso a paso con un builder fluido para evitar constructores telescópicos. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Patrón Builder con API fluida»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Singleton: implementaciones seguras para hilos
- Patrón Factory Method
- Abstract Factory para familias de productos
- Patrón Builder con API fluida