Skip to content

Instantly share code, notes, and snippets.

@AlexGalhardo
Created August 24, 2019 21:46
Show Gist options
  • Select an option

  • Save AlexGalhardo/6e5af6b07996fdba4b72ba6eade850c9 to your computer and use it in GitHub Desktop.

Select an option

Save AlexGalhardo/6e5af6b07996fdba4b72ba6eade850c9 to your computer and use it in GitHub Desktop.
  • Permite às classes delegar para subclasses decidirem, isso é feito através da criação de objetos que chamam o método fabrica especificado numa interface e implementado por um classe filha ou implementado numa classe abstrata e opcionalmente sobrescrito por classes derivadas.

  • Estrutura

  • O padrão Factory Method, da forma como foi descrito no livro Design Patterns: Elements of Reusable Object-Oriented Software, contém os seguintes elementos:

    • Creator(Criador abstrato) — declara o factory method (método de fabricação) que retorna o objeto da classe Product (produto). Este elemento também pode definir uma implementação básica que retorna um objeto de uma classe ConcreteProduct (produto concreto) básica;
    • ConcreteCreator(Criador concreto) — sobrescreve o factory method e retorna um objeto da classe ConcreteProduct;
    • Product(Produto abstrato) — define uma interface para os objectos criados pelo factory method;
    • ConcreteProduct(Produto concreto) — uma implementação para a interface Product.
  • Finalidade

    • Criar um objeto geralmente requere processos complexos não apropriados para incluir dentro da composição do objeto. A criação do objeto talvez necessite de uma duplicação de código significativa, talvez necessite informações não acessíveis para a composição do objeto, talvez não providencie um grau de abstração suficiente, ou então não faça parte da composição das preocupações do objeto. O padrão de design método fabrica maneja/trata esses problemas definindo um método separado para criação dos objetos, no qual as subclasses possam sobrescrever para especificar o "tipo derivado" do produto que vai ser criado.
  • Utilização

    • Este padrão é muito utilizado em frameworks para definir e manter relacionamentos entre objetos. O framework Spring, dependendo da configuração, pode utilizar um Factory Method para criar os seus beans.[1]
    • Este padrão pode ser utilizado na construção de um framework que suporta aplicações que apresentam múltiplos documentos ao usuário. Normalmente este tipo de aplicação manipula um número variável de formatos de documento e, por isso, este framework deve ser flexível o bastante para suportar qualquer formato. Uma solução para este problema poderia disponibilizar, no framework, o código para alguns dos formatos mais utilizados. Mas, na prática, esta solução seria uma implementação pouco flexível, e até mesmo incompleta, já que é custoso implementar os mais variados formatos. O padrão Factory Method propõe uma solução que deixa para o cliente (a implementação da aplicação) a tarefa de suportar os formatos necessários e para o framework o papel de definição de uma abstração que oferece uma interface única para criação de documentos.
    • Este framework seria baseado em duas classes abstratas, que representam a Aplicação e o Documento. O cliente do framework fornece um par de classes concretas, uma aplicação e o respectivo documento, para cada um dos formatos de Documento suportados pela Aplicação. Se for necessário apresentar um documento que suporte desenho, por exemplo, o cliente deve disponibilizar as classes AplicacaoDesenho e DocumentoDesenho (supondo que o sufixo "Desenho" indique classes que suportam esta funcionalidade).
    • O objetivo do Factory Method está em diversas classes que implementam a mesma operação, retornarem o mesmo tipo abstrato, mas internamente instanciam diferentes classes que o implementam. Com o Factory Method o criador do objeto faz uma escolha de qual classe instanciar para o cliente. Para ser um Factory Method o método precisa retornar uma interface ou uma classe abstrata e, dependendo das necessidades do cliente, criar um objeto determinado como retorno. Um exemplo clássico do Factory Method são os iteradores tanto em Java como em .NET.
  • Consequências

    • Positivas: Baixo acoplamento, maior flexibilidade e elimina a necessidade de acoplar classes específicas para aplicação em nível de código.
    • Negativas: Alto número de classes, podendo sobrecarregar o sistema.
  • Aplicações

    • Quando a classe não antecipa a classe do objeto que quer criar.
    • Uma classe quer suas subclasses para especificar os objetos que cria.
    • Quando você não quer que o usuário tenha que saber de cada subclasse.
    • Encapsular a criação de objetos.

Pincel.java

package pintura;

/**
 * 
 * Classe de exemplo mostrando a utilização  
 * do Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

public class Pincel {
    
    /**
    *    Neste exemplo consideramos que ao chamar o método, serão pintadas as 
    *    cores verde, azul e vermelho, nesta sequência
    */
    
    public void pintar(){
        
        Cor corEscolhida;
        FactoryCor fabricaDeCor = new FactoryCor();
        
        //Pintando de verde
        corEscolhida = fabricaDeCor.getCor("verde"); 
        corEscolhida.colorir();
        
        //Pintando de azul
        corEscolhida = fabricaDeCor.getCor("azul"); 
        corEscolhida.colorir(); 
        
        //Pintando de azul
        corEscolhida = fabricaDeCor.getCor("vermelho"); 
        corEscolhida.colorir(); 
        
    }
    
}

Verde.java

package pintura;


/**
 * 
 * Classe, implementação da Interface cor
 * Do pacote de exemplo Pintura que demonstra o 
 * Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

public class Verde implements Cor {
    
    @Override
    public void colorir(){
        System.out.println("Colorido de Verde");
    }
    
}

Vermelho.java

package pintura;


/**
 * 
 * Classe, implementação da Interface cor
 * Do pacote de exemplo Pintura que demonstra o 
 * Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

public class Vermelho implements Cor{
    
    @Override
    public void colorir(){
        System.out.println("Colorido de Vermelho");
    }
}

Cor.java

package pintura;

/**
 * 
 * Interface cor
 * Do pacote de exemplo Pintura que demonstra o 
 * Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

/**
 *
 * @author Thiago
 */
public interface Cor {
    void colorir();
}

Azul.java

package pintura;


/**
 * 
 * Classe, implementação da Interface cor
 * Do pacote de exemplo Pintura que demonstra o 
 * Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

public class Azul implements Cor {
    
    @Override
    public void colorir(){
        System.out.println("Colorido de Azul");
    }
}

FactoryCor.java

package pintura;

/**
 * 
 * Classe, fábrica de objetos do tipo cor
 * Do pacote de exemplo Pintura que demonstra o 
 * Padrão de Projeto GOF - Factory Method
 * 
 * @author Thiago Toledo <javaephp@gmail.com>
 * 
 */

public class FactoryCor {
    
    /**
     *
     * @param nomeDaCor
     * @return
     */
    public Cor getCor(String nomeDaCor){
        
        switch (nomeDaCor) {
            
            case "verde":
                return new Verde();
                
            case "azul":
                return new Azul();
                
            case "vermelho":
                return new Vermelho();
                
            default:
                return null;
                
        }        
        
    }
    
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment