Sobes.tech
Middle

O que é o padrão de projeto 'construtor' (Builder)?

sobes.tech IA

Resposta da IA

O padrão "Builder" (Construtor) é um padrão de design criacional destinado a criar objetos complexos passo a passo. Ele separa o processo de construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção pode criar diferentes representações.

Princípios de funcionamento:

  1. Separação: Separa a lógica de criação do objeto do próprio objeto.
  2. Delegação: O código cliente (Director) delega a criação do objeto a uma classe separada (Builder).
  3. Construção passo a passo: O objeto é construído a partir de componentes usando um conjunto de métodos do construtor.

Principais participantes:

  • Produto: Objeto complexo que queremos construir. Não depende do processo de criação.
  • Builder: Interface abstrata que define os passos para construir o Produto.
  • ConcreteBuilder: Implementação concreta de Builder, que realiza os passos de construção e fornece um método para obter o Produto finalizado.
  • Director (Opcional): Define a ordem de chamada dos passos de construção. Não é obrigatório, o código cliente pode interagir diretamente com ConcreteBuilder.

Vantagens:

  • Permite criar objetos com muitos parâmetros opcionais de forma mais legível do que usando construtores com múltiplos argumentos ou cadeias de setters.
  • Permite criar diferentes variações de um mesmo objeto usando o mesmo processo de construção.
  • Esconde a estrutura interna do objeto que está sendo criado.

Desvantagens:

  • Pode aumentar o número de classes no projeto (Builder, ConcreteBuilder, Product, Director).

Exemplo de uso: Criação de um objeto da classe Pizza com diferentes ingredientes.

// Produto
public 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 setToppings(List<String> toppings) { this.toppings = toppings; }

    @Override
    public String toString() {
        return "Pizza com massa=" + dough + ", molho=" + sauce + ", queijo=" + cheese + ", ingredientes=" + toppings;
    }
}
// Builder
public interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildCheese();
    void addTopping(String topping);
    Pizza getPizza();
}
// ConcreteBuilder
public class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public MargheritaPizzaBuilder() {
        this.pizza = new Pizza();
        this.pizza.setToppings(new ArrayList<>()); // Inicialização da lista
    }

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

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

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

    @Override
    public void addTopping(String topping) {
        // A Margherita não adiciona toppings, além dos básicos
    }

    @Override
    public Pizza getPizza() {
        return this.pizza;
    }
}
// Director (Opcional)
public class Kitchen {
    private PizzaBuilder pizzaBuilder;

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

    public Pizza getPizza() {
        return pizzaBuilder.getPizza();
    }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildCheese();
        // Podem ser chamados outros métodos, por exemplo addTopping() em outro builder
    }
}

Uso:

// Código cliente
Kitchen kitchen = new Kitchen();
PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

kitchen.setPizzaBuilder(margheritaBuilder);

kitchen.constructPizza();

Pizza margherita = kitchen.getPizza();
System.out.println(margherita); // Saída: Pizza com massa=Massa fina, molho=Molho de tomate, queijo=Mozzarella, ingredientes=[]