Builder

Solução Proposta

Fornece uma interface que separa 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

Exemplo

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

Builder - 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