Factory Method

Solução Proposta

Fornece uma interface para criação de um objeto, de modo que as subclasses são responsáveis por decidirem que classe instanciar.

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 2 seguintes modelos/montadoras:
 
Palio – Fiat
Gol – Volkswagen
 
Sempre que for necessário criar um carro Palio, por exemplo, a fábrica Fiat deverá ser acionada, da mesma forma, quando um carro Gol precisar ser criado, a fábrica volkswagem deverá ser acionada. Podemos observar que precisamos de uma fábrica para cada tipo de carro, assim o uso do padrão Factory Method permite que tais objetos sejam criados a partir de uma interface, deixando que as subclasses decidam que classe instanciar. Isso é feito a partir de um método fábrica implementado de forma polimórfica. No exemplo abaixo as classes FiatConcreteCreator e VolksConcreteCreator reescrevem o método fábrica herdado de CarCreator.

Diagrama de Classe

Factory Method - Diagrama

Participantes

  • Product(Car): Define a interface de objetos que o método fábrica cria.
  • ConcreteProduct(ConcreteProductGol, ConcreteProductPalio): implementa a interface de Product.
  • Creator(CarCreator): Declara o método fábrica, o qual retorna um objeto do tipo Product. Creator pode também definir uma implementação por omissão do método factory que retorna por omissão um objeto ConcreteProduct. Pode chamar o método factory para criar um objeto Product.
  • ConcreteCreator(VolksConcreteCreator, FiatConcreteCreator): Redefine o método-fábrica para retornar a uma instância de um ConcreteProduct.

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

/**
 *
 * @author patrick
 */
public abstract class Car {
    
    private String model;     
    private String factory;     
    private String category;    
    
    
  public void showInformation() {
              
        System.out.println("Model:" + this.getModel()+ " \nFactory:" + this.getFactory() +  "\nCategory: " + this.getCategory());

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

   
}
/*
 * 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 factorymethod2;

/**
 *
 * @author patrick
 */
public abstract class CarCreator {
    
    public void buildCar() 
	{
		Car carro = factoryMethod();
	}
	
	protected abstract Car factoryMethod();
    
    
}
/*
 * 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 factorymethod2;

import javax.swing.JOptionPane;

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

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
                       
                    CarCreator creator1 = new FiatConcreteCreator();              
                    creator1.buildCar();
                    
                    CarCreator creator2 = new VolksConcreteCreator();              
                    creator2.buildCar();
                
        
    }
    
}
/*
 * 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 factorymethod2;

/**
 *
 * @author patrick
 */
public class ConcreteProductGol extends Car{

public ConcreteProductGol(){
     
        this.setModel("Gol");
        this.setFactory("Volks");
        this.setCategory("Hatch");
        this.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 factorymethod2;

/**
 *
 * @author patrick
 */
public class ConcreteProductPalio extends Car{
    
public ConcreteProductPalio(){
       
        this.setModel("Palio");
        this.setFactory("Fiat");
        this.setCategory("Hatch");
        this.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 factorymethod2;

/**
 *
 * @author patrick
 */
public class FiatConcreteCreator extends CarCreator{
    

protected Car factoryMethod(){
           
    return new ConcreteProductPalio();
                 
        }
}
/*
 * 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 factorymethod2;

/**
 *
 * @author patrick
 */
public class VolksConcreteCreator extends CarCreator{
    

protected Car factoryMethod(){
           
        return new ConcreteProductGol();
                 
        }
}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados