Prototype

Intenção

Especificar os tipos de objetos a serem criados usando uma instância-protótipo e criar novos objetos pela cópia desse protótipo.

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 seguintes conjuntos modelos/montadoras: 
 
Siena – Fiat
Palio – Fiat
Uno -Fiat
voyage – Volkswagem
Gol - Volkswagem
Up - Volkswagem
 
A principio, seria necessário uma classe fábrica para cada objeto específico de cada montadora, além de uma classe concreta para cada produto das fábricas. Por exemplo, uma fábrica Fiat criaria objetos Siena, Palio e uno, esses objetos possuiriam suas classes concretas específicas, da mesma forma uma fábrica Volkswagen criaria objetos Voyage, Gol e Up, que também possuiriam sua devidas classes concretas. Observa-se aqui uma hierarquia de classes fábricas e uma outra hierarquia de classes produtos, o que gera uma explosão de classes na aplicação a medida que novos produtos venham a aparecer.
Para reduzir a necessidade de se ter uma fábrica para cada montadora, o padrão Prototype permite clonar um protótipo em vez de pedir a uma fábrica para construir um novo objeto. No exemplo abaixo CarPrototype representa um protótipo de qualquer tipo de carro, onde as classes FiatPrototype e VolksPrototype especializam esse prototipo para carros de suas respectivas montadoras, ou seja Fiat e Volkswagen.

Diagrama de Classe

Exemplo #1 - Diagrama

Participantes

  • Prototype(CarPrototype): declara uma classe abstrata para clonar a si próprio.
  • ConcretePrototype(FiatPrototype, VolksPrototype): implementa uma operação para clonar a si próprio.
  • Client(Client): Cria um novo objeto solicitando a um protótipo que clone a si próprio.

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 prototype2;

/**
 *
 * @author patrick
 */
public abstract class CarPrototype {
    

    private String model;
    private String factory;     
    private String category; 
    private String year;

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }
    
     public String getModel() {
        return model;
    }
 
    public void setModel(String model) {
        this.model = model;
    }

    public String getFactory() {
        return factory;
    }

    public void setFactory(String factory) {
        this.factory = factory;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
       this.category = category;
    }
 
    public String showInformation() {
       return "Model:" + this.getModel()+ " \nFactory:" + this.getFactory() +  "\nCategory: " + this.getCategory()+  "\nYear: " + this.getYear();
        
    } 
 
    public abstract CarPrototype getClone();
 
  
   
}

/*
 * 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 prototype2;


/**
 *
 * @author patrick
 */
public class Client {
   
       
    public static void main(String[] args) {
    
     
        
    FiatPrototype protFiat = new FiatPrototype();
                   
    CarPrototype car1 = protFiat.getClone();     
   
    car1.setModel("Palio Fire");
    car1.setCategory("Hatch");
    car1.setYear("2014");
    
     
    CarPrototype car2 = protFiat.getClone();
    
    car2.setModel("Siena");
    car2.setCategory("Sedan");
    car2.setYear("2014");
 
    System.out.println(car1.showInformation());
    System.out.println("=========================");
    System.out.println(car2.showInformation());
        
        
    }
    
}
/*
 * 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 prototype2;

/**
 *
 * @author patrick
 */


public class FiatPrototype extends CarPrototype {
    
       public FiatPrototype() {
            
        this.setModel("Fiat 0001");
        this.setFactory("Fiat");
        this.setCategory("Hatch");
        this.setYear("2000");
    }
        
    protected FiatPrototype(FiatPrototype fiat_Prototype) { //constructor by copy
        
        this.setModel(fiat_Prototype.getModel());
        this.setFactory(fiat_Prototype.getFactory());
        this.setCategory(fiat_Prototype.getCategory());
        this.setYear(fiat_Prototype.getYear());
                
    }
    
       
    public FiatPrototype getClone() {
        return new FiatPrototype(this);
    }
    
}
/*
 * 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 prototype2;

/**
 *
 * @author patrick
 */

public class VolksPrototype extends CarPrototype {
    
      public VolksPrototype() {
        this.setModel("Volks 0001");
        this.setFactory("volks");
        this.setCategory("Hatch");
        this.setYear("2000");
    }
 
    
    protected VolksPrototype(VolksPrototype volks_Prototype) { //constructor by copy
       
        this.setModel(volks_Prototype.getModel());
        this.setFactory(volks_Prototype.getFactory());
        this.setCategory(volks_Prototype.getCategory());
        this.setYear(volks_Prototype.getYear());
        
    }
    
      
    public VolksPrototype getClone() {
        return new VolksPrototype(this);
    }
    
}
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: