Menu
Coddy logo textTech

Patrón Builder

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 67 de 87.

El patrón Builder es un patrón de diseño creacional que resuelve un problema común: construir objetos complejos con muchos parámetros opcionales. En lugar de crear múltiples constructores o pasar null para los parámetros no utilizados, Builder te permite construir objetos paso a paso.

Considera crear un objeto User con campos obligatorios (nombre, correo electrónico) y otros opcionales (edad, teléfono, dirección). Sin un Builder, necesitarías constructores telescópicos o un constructor desordenado con muchos parámetros. El patrón Builder ofrece un enfoque más limpio:

public class User {
    private final String name;    // requerido
    private final String email;   // requerido
    private final int age;        // opcional
    private final String phone;   // opcional
    
    private User(UserBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.phone = builder.phone;
    }
    
    public static class UserBuilder {
        private final String name;
        private final String email;
        private int age;
        private String phone;
        
        public UserBuilder(String name, String email) {
            this.name = name;
            this.email = email;
        }
        
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
}

Los métodos del Builder devuelven this, lo que permite el encadenamiento de métodos: una forma fluida y legible de construir objetos:

User user = new User.UserBuilder("Alice", "alice@email.com")
    .age(25)
    .phone("555-1234")
    .build();

Observa que el constructor de User es privado: los objetos solo pueden crearse mediante el Builder. Este patrón resulta especialmente útil cuando los objetos tienen muchos campos opcionales, ya que hace que tu código sea más legible y menos propenso a errores que las listas largas de parámetros.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de pedidos de pizza usando el patrón Builder! En lugar de lidiar con un constructor que recibe docenas de parámetros para todas las posibles coberturas y opciones, crearás un builder fluido que hace que la personalización de la pizza sea clara y legible.

Organizarás tu código en dos archivos:

  • Pizza.java: Crea una clase Pizza que use el patrón Builder para su construcción. Tu pizza debe tener los siguientes campos:

    size (String) - obligatorio, representa el tamaño de la pizza

    cheese (boolean) - opcional, su valor predeterminado es false

    pepperoni (boolean) - opcional, su valor predeterminado es false

    mushrooms (boolean) - opcional, su valor predeterminado es false

    El constructor de Pizza debe ser privado y aceptar únicamente un PizzaBuilder como parámetro, copiando todos los valores del builder a los campos de la pizza.

    Incluye un método getDescription() que devuelva una cadena con este formato: [size] Pizza with: [toppings], donde toppings es una lista separada por comas de las coberturas cuyo valor sea true (Cheese, Pepperoni, Mushrooms). Si no se selecciona ninguna cobertura, la parte de toppings debe decir simplemente no toppings.

    Crea una clase interna estática PizzaBuilder con:

    • Un constructor que reciba el parámetro obligatorio size
    • Métodos cheese(), pepperoni() y mushrooms() que establezcan su boolean correspondiente en true y devuelvan this para permitir el encadenamiento
    • Un método build() que devuelva una nueva Pizza
  • Main.java: ¡Demuestra el builder de tu pizza en acción! Recibirás cuatro entradas: el tamaño de la pizza (String) y tres valores de sí/no (Strings) que indican si se deben añadir queso, pepperoni y champiñones, respectivamente.

    Crea un PizzaBuilder con el tamaño proporcionado. Después, según cada entrada de sí/no, encadena los métodos de cobertura correspondientes. Si la entrada es "yes", llama a ese método de cobertura; si es "no", omítelo. Finalmente, llama a build() para crear tu pizza.

    Imprime el resultado de llamar a getDescription() en tu pizza completada.

Recibirás cuatro entradas en orden: size (String), add cheese (String: "yes" o "no"), add pepperoni (String: "yes" o "no"), add mushrooms (String: "yes" o "no").

Por ejemplo, con las entradas Large, yes, no, yes, tu salida sería: Large Pizza with: Cheese, Mushrooms

¡Observa cómo el patrón Builder te permite construir pizzas con cualquier combinación de coberturas sin necesitar constructores separados para cada posibilidad!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String size = scanner.nextLine();
        String addCheese = scanner.nextLine();
        String addPepperoni = scanner.nextLine();
        String addMushrooms = scanner.nextLine();
        
        // TODO: Crea un PizzaBuilder con el tamaño dado
        // TODO: Encadena los métodos de toppings según las entradas de sí/no
        // TODO: Construye la pizza e imprime su descripción
        
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online