Sobes.tech
Middle

¿Qué es un constructor (Builder) en el contexto del desarrollo de software?

sobes.tech AI

Respuesta de la IA

Patrón de diseño que separa la construcción de un objeto complejo de su representación, permitiendo crear diferentes representaciones del mismo proceso de construcción.

Características clave:

  • Separación de responsabilidades: La lógica de creación del objeto (pasos de construcción) y la representación del objeto (producto final) están separadas.
  • Construcción paso a paso: El objeto se construye paso a paso, lo que hace que el proceso sea más flexible y comprensible.
  • Diferentes representaciones: El mismo proceso de construcción puede usarse para crear diferentes variaciones del objeto.
  • Encapsulación: Los detalles de la creación del objeto están ocultos al cliente, lo que simplifica su uso.

Participantes principales:

  • Builder (Constructor): Interfaz o clase abstracta que define los pasos para crear partes del producto.
  • ConcreteBuilder (Constructor Concreto): Implementación concreta del Constructor, que realiza la construcción real de las partes del producto y almacena el resultado.
  • Director (Director): Clase que usa un objeto ConcreteBuilder para construir el producto, llamando a los métodos correspondientes en una secuencia determinada.
  • Product (Producto): Objeto complejo que se construye.

Ejemplo de uso:

Creación de un objeto Pizza con diferentes ingredientes:

// Producto
class Pizza {
    private String dough;
    private String sauce;
    private String cheese;
    private List<String> toppings;

    public void setDough(String dough) { this.dough = dough; }
    public void setSauce(String sauce) { this.sauce = sauce; }
    public void setCheese(String cheese) { this.cheese = cheese; }
    public void addTopping(String topping) {
        if (toppings == null) {
            toppings = new ArrayList<>();
        }
        toppings.add(topping);
    }

    @Override
    public String toString() {
        return "Pizza con masa: " + dough + ", salsa: " + sauce + ", queso: " + cheese + ", toppings: " + toppings;
    }
}

// Interfaz del Constructor
interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildCheese();
    void addTopping(String topping);
    Pizza getResult();
}

// Constructor Concreto
class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public MargheritaPizzaBuilder() {
        this.pizza = new Pizza();
    }

    @Override
    public void buildDough() {
        pizza.setDough("Masa fina");
    }

    @Override
    public void buildSauce() {
        pizza.setSauce("Salsa de tomate");
    }

    @Override
    public void buildCheese() {
        pizza.setCheese("Mozzarella");
    }

    @Override
    public void addTopping(String topping) {
        // La Margherita no tiene toppings adicionales por defecto
    }

    @Override
    public Pizza getResult() {
        return pizza;
    }
}

// Director
class Cook {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) {
        pizzaBuilder = pb;
    }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildCheese();
        // Se pueden agregar toppings adicionales aquí según el tipo de pizza o requisitos
    }
}

// Código del cliente
public class PizzaShop {
    public static void main(String[] args) {
        Cook cook = new Cook();
        PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

        cook.setPizzaBuilder(margheritaBuilder);
        cook.constructPizza();

        Pizza pizza = margheritaBuilder.getResult();
        System.out.println(pizza);
    }
}

Se aplica cuando:

  • Es necesario crear un objeto complejo con múltiples parámetros opcionales.
  • El proceso de creación del objeto es secuencial e incluye múltiples pasos.
  • Se requiere crear diferentes variaciones del mismo objeto usando el mismo algoritmo de construcción.
  • Es necesario evitar constructores con muchos parámetros ("constructor telescópico").

Ventajas:

  • Mejora la legibilidad y mantenibilidad del código.
  • Proporciona flexibilidad en la creación de objetos.
  • Permite crear objetos inmutables.
  • Elimina la necesidad de múltiples constructores.

Desventajas:

  • Puede aumentar la cantidad de clases en el proyecto (para cada tipo de objeto y constructor).
  • Requiere un esfuerzo inicial en el diseño.