Sobes.tech
Middle

O que é um construtor (Builder) no contexto do desenvolvimento de software?

sobes.tech IA

Resposta da IA

Padrão de projeto que separa a construção de um objeto complexo da sua representação, permitindo criar diferentes representações do mesmo processo de construção.

Características principais:

  • Separação de responsabilidades: A lógica de criação do objeto (passos de construção) e a representação do objeto (produto final) estão separadas.
  • Construção passo a passo: O objeto é construído passo a passo, tornando o processo mais flexível e compreensível.
  • Diferentes representações: O mesmo processo de construção pode ser usado para criar várias variações do objeto.
  • Encapsulamento: Os detalhes da criação do objeto estão ocultos ao cliente, facilitando seu uso.

Principais participantes:

  • Builder (Construtor): Interface ou classe abstrata que define os passos para criar partes do produto.
  • ConcreteBuilder (Construtor Concreto): Implementação concreta do construtor, que realiza a construção real das partes do produto e armazena o resultado.
  • Director (Diretor): Classe que usa um objeto ConcreteBuilder para construir o produto, chamando os métodos apropriados em uma sequência determinada.
  • Product (Produto): Objeto complexo que está sendo construído.

Exemplo de uso:

Criação de um objeto Pizza com diferentes ingredientes:

// Produto
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 com massa: " + dough + ", molho: " + sauce + ", queijo: " + cheese + ", toppings: " + toppings;
    }
}

// Interface do construtor
interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildCheese();
    void addTopping(String topping);
    Pizza getResult();
}

// Construtor concreto
class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

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

    @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 tem toppings extras por padrão
    }

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

// Diretor
class Cook {
    private PizzaBuilder pizzaBuilder;

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

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildCheese();
        // Toppings adicionais podem ser adicionados aqui com base no tipo de pizza ou requisitos
    }
}

// Código do 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);
    }
}

Aplicação quando:

  • É necessário criar um objeto complexo com múltiplos parâmetros opcionais.
  • O processo de criação do objeto é sequencial e envolve várias etapas.
  • É preciso criar várias variações do mesmo objeto usando o mesmo algoritmo de construção.
  • É necessário evitar construtores com muitos parâmetros ("construtor telescópico").

Vantagens:

  • Melhora a legibilidade e a manutenção do código.
  • Proporciona flexibilidade na criação de objetos.
  • Permite criar objetos imutáveis.
  • Elimina a necessidade de múltiplos construtores.

Desvantagens:

  • Pode aumentar o número de classes no projeto (para cada tipo de objeto e cada construtor).
  • Requer um esforço inicial de design.