Builder

Intenção

Separar a construção de um objeto complexo da sua representação de modo que o mesmo processo de construção possa criar diferentes representações.

Vantagens

Desvantagens

Exemplos

Exemplo #1

Um sistema de software deve ser desenvolvido para controlar um conjunto de diferentes tipos de carros, cada um de uma determinada montadora. Para exemplificar suponha os dois seguintes modelos/montadoras:
 
Palio – Fiat
Gol – Volkswagen
 
Embora os objetos acima sejam do mesmo tipo, partes deles são criadas de forma diferente e complexa, neste caso as partes são o preço e o chassi. Assim, sempre que um objeto Palio for criado seu preço e o número de seu chassi são criados de forma diferente de um objeto Gol. Podemos observar que teremos diferentes representações de um objeto complexo, Palio e Gol, dessa forma o uso do padrão Builder permite separar a construção desses objetos complexos das suas representações de modo que o mesmo processo de construção possa criar diferentes representações. No exemplo abaixo o processo de criação buildCar cria tanto objetos Palio quanto objetos Gol.

Diagrama de Classe

Exemplo #1 - Diagrama

Participantes

  • Builder(CarBuilder): Especifica uma interface para criação de partes de um objeto-produto.
  • ConcreteBuilder(FiatConcreteBuilder, VolksConcreteBuilder): constrói e monta partes do produto pela implementação da interface de Builder; define e mantém a representação que cria; fornece uma interface para recuperação do produto.
  • Director(DealersDirector): constrói um objeto usando a interface de Builder.
  • Product(CarProduct): representa o objeto complexo em construção. ConcreteBuilder constrói a representação interna do produto e define o processo pelo qual ele é montado; inclui classes que definem as partes constituintes, inclusive as interfaces para a montagem das partes no resultado final.
 

Código

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */
public abstract class CarBuilder {
 
   
    public abstract void buildPreco();
    
    public abstract void buildchassi();
 
 
    
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */

public class CarProduct {     
    private double   price;    
    private String   chassi;
    private String motor;     
    private String yearManufacture;     
    private String serialNumber;
    private String model;     
    private String automaker; 

    /**
     * @return the yearManufacture
     */
    public String getYearManufacture() {
        return yearManufacture;
    }

    /**
     * @param yearManufacture the yearManufacture to set
     */
    public void setYearManufacture(String yearManufacture) {
        this.yearManufacture = yearManufacture;
    }

    /**
     * @return the serialNumber
     */
    public String getSerialNumber() {
        return serialNumber;
    }

    /**
     * @param serialNumber the serialNumber to set
     */
    public void setSerialNumber(String serialNumber) {
        this.serialNumber = serialNumber;
    }

    /**
     * @return the motor
     */
    public String getMotor() {
        return motor;
    }

    /**
     * @param motor the motor to set
     */
    public void setMotor(String motor) {
        this.motor = motor;
    }

    /**
     * @return the model
     */
    public String getModel() {
        return model;
    }

    /**
     * @param model the model to set
     */
    public void setModel(String model) {
        this.model = model;
    }

    /**
     * @return the automaker
     */
    public String getAutomaker() {
        return automaker;
    }

    /**
     * @param automaker the automaker to set
     */
    public void setAutomaker(String automaker) {
        this.automaker = automaker;
    }

    /**
     * @return the price
     */
    public double getPrice() {
        return price;
    }

    /**
     * @param price the price to set
     */
    public void setPrice(double price) {
        this.price = price;
    }

    /**
     * @return the chassi
     */
    public String getChassi() {
        return chassi;
    }

    /**
     * @param chassi the chassi to set
     */
    public void setChassi(String chassi) {
        this.chassi = chassi;
    }
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */
public class Client {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       
    
    FiatConcreteBuilder typeCar = new FiatConcreteBuilder();    
    DealersDirector dealer = new DealersDirector(typeCar);
    dealer.buildCar();
    CarProduct car = typeCar.getCar();
    
    System.out.println("Car: " + car.getModel() + "/" + car.getAutomaker() + " \nYear:   " + car.getYearManufacture()
            + "         \nMotor: " + car.getMotor()
            + "         \nChassi: " + car.getChassi() 
            + "         \nPrice: " + car.getPrice());
 
    System.out.println();
 
    VolksConcreteBuilder typeCar2 = new VolksConcreteBuilder();    
    dealer = new DealersDirector(typeCar2);
    dealer.buildCar();
    CarProduct car2 = typeCar2.getCar();
    
    System.out.println("Car: " + car2.getModel() + "/" + car2.getAutomaker() + " \nyear:   " + car2.getYearManufacture()
            + "         \nMotor: " + car2.getMotor()
            + "         \nChassi: " + car2.getChassi() 
            + "         \nPrice: " + car2.getPrice());
                
    }
    
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */
public class DealersDirector {
    protected CarBuilder automaker;
 
    public DealersDirector(CarBuilder automaker) {
        this.automaker = automaker;
    }
 
    public void buildCar() {
        automaker.buildPreco();
        automaker.buildchassi();
        
    }
 
 //   public CarroProduct getCarro() {
 //       return automaker.getCarro();
  //  }
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */
public class FiatConcreteBuilder extends CarBuilder {
 
    protected CarProduct car;
 
    public FiatConcreteBuilder() {
        car = new CarProduct();
         car.setYearManufacture("2011");
         car.setSerialNumber("129834");
         car.setMotor("Fire Flex 1.0");
         car.setModel("Palio");
         car.setAutomaker("Fiat");
         
    }
    
    @Override
    public void buildPreco() {
        // Operação complexa. 
        car.setPrice(15000 + (15000 * 0.3) + (15000 * 0.15) + (15000 * 0.638));
    }
    
  
    @Override
    public void buildchassi() {
        // Operação complexa.
       car.setChassi(car.getYearManufacture() + car.getSerialNumber());
    }
 
  
    
    public CarProduct getCar() {
        return car;
    }
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Builder2;

/**
 *
 * @author patrick
 */
public class VolksConcreteBuilder extends CarBuilder{
  
    protected CarProduct car;
 
    public VolksConcreteBuilder() {
        car = new CarProduct();
          car.setYearManufacture("2013");
          car.setSerialNumber("309844");
          car.setMotor("Versão 1.0");
          car.setModel("Gol");
          car.setAutomaker("Volkswagem");
    }
    
    @Override
    public void buildPreco() {
        // Operação complexa. 
        car.setPrice(17000 + (17000 * 0.3) + (17000 * 0.15) + (17000 * 0.638));
    }
    
    @Override
    public void buildchassi() {
        // Operação complexa.
        car.setChassi(car.getYearManufacture() + car.getSerialNumber() + car.getYearManufacture() );
        
    }
 
           
       public CarProduct getCar() {
        return car;
    }
}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados

Este Padrão pode ser usado para resolver os seguintes problemas: