Abstract Factory

Intenção

Fornece uma interface para criação de famílias de objetos relacionadas ou dependentes sem especificar suas classes concretas.

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 de categoria, modelos/montadoras: 
Sedan:
Siena – Fiat
voyage – Volkswagem
 
Hatch:
Palio – Fiat
Gol – Volkswagem
 
Sempre que for necessário criar um carro Palio, por exemplo, a fábrica Fiat deverá ser acionada sabendo que trata-se de um carro hatch, da mesma forma, quando um carro voyage precisar ser criado, a fábrica volkswagem deverá ser acionada sabendo que trata-se de um carro Sedan, e assim por diante. Como podemos observar temos uma situação em que se configura a criação de famílias de objetos, assim o uso do padrão Abstract factory permite que tais objetos sejam criados sem que seja necessário especificar as suas classes concretas. No exemplo abaixo, temos fábricas concretas para carros da montadora Fiat, FiatFactory, e Volkswagem, VolksFactory. Cada uma dessas fábricas sabe criar carros do tipo Sedan e Hatch. 

Diagrama de Classe

Exemplo #1 - Diagrama

Participantes

  •  AbstractFactory(CarFactory): Declara uma interface para operações que criem objetos-produtos abstratos.
  • ConcreteFactory(FiatFactory, VolksFactory): implementa as operações que criam objeto-produto concretos.
  • AbstractProduct(HatchCar, SedanCar): declara uma interface para um tipo de objeto-produto.
  • ConcreteProduct(Gol, Palio, Siena, Voyage): define um objeto-produto a ser criado pela correspondente fábrica concreta. Implementa a interface de AbstractProduct.
  • Client: usa somente interfaces declaradas pela classse AbstractFactory e AbstractProduct.

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

/**
 *
 * @author patrick
 */
public abstract class CarFactory {
    
 public abstract SedanCar   buildSedanCar();
 public abstract HatchCar   buildHatchCar();
    
}
/*
 * 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 abfactory2;

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

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
    CarFactory factory = new FiatFactory();
    SedanCar sedan = factory.buildSedanCar();
    HatchCar hatch = factory.buildHatchCar();
    
    sedan.showSedanInformation();
    System.out.println();
    hatch.showHatchInformation();
    System.out.println();
 
    factory = new VolksFactory();
    sedan = factory.buildSedanCar();
    hatch = factory.buildHatchCar();
    
    sedan.showSedanInformation();
    System.out.println();
    hatch.showHatchInformation(); 
        
    }
    
}
/*
 * 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 abfactory2;

/**
 *
 * @author patrick
 */
public class FiatFactory extends CarFactory {
 
    
    
    public SedanCar buildSedanCar() {
        return new Siena();
    }
 
    
    
    public HatchCar buildHatchCar() {
        return new Palio();
    }
 
}

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

/**
 *
 * @author patrick
 */
public class Gol extends HatchCar {
    
    public void showHatchInformation() {
        
        System.out.println("Model: Gol \nFactory: Volks \nCategory:Hatch");
    }

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

/**
 *
 * @author patrick
 */
public abstract class HatchCar {
       
    public abstract void showHatchInformation();  

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

/**
 *
 * @author patrick
 */
public class Palio extends HatchCar {
 
    
    public void showHatchInformation() {
              
        System.out.println("Model: Palio \nFactory: Fiat \nCategory:Hatch");
    }
 
}
/*
 * 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 abfactory2;

/**
 *
 * @author patrick
 */
public abstract class SedanCar {
    
    public abstract void showSedanInformation();
  
}
/*
 * 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 abfactory2;

/**
 *
 * @author patrick
 */
public class Siena extends SedanCar {
 
    public void showSedanInformation() {
        
        System.out.println("Model: Siena \nFactory: Fiat \nCategory:Sedan");
    }
 
}
/*
 * 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 abfactory2;

/**
 *
 * @author patrick
 */
public class VolksFactory extends CarFactory {
 

    
    public SedanCar buildSedanCar() {
        return new Voyage();
    }
 

    
    public HatchCar buildHatchCar() {
        return new Gol();
    }
 
}
/*
 * 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 abfactory2;

/**
 *
 * @author patrick
 */
public class Voyage extends SedanCar { 
    
    public void showSedanInformation() {
        
        System.out.println("Model: Voyage \nFactory: Volks \nCategory:Sedan");
    }
    
}


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: