Factory Method

Bom dia pessoal, estou criando uma aplicação simples para uma disciplina da faculdade.
Resolvi implementar alguns Design Patterns. Ao tentar implementar Factory Method para me retornar a instancia de um novo objeto criado
encontrei dificuldades.

Na Bean fiz assim

[code]public void Salvar(){

    Funcionario F = new Funcionario();
    F.setCargo("Diretor Comercial");
    F.setLogin("administrador");
    F.setSenha("123");
    F.setNivel(1);
    
    IFuncionario dao = FactoryDAO.creatObject("FuncionarioDAO");
    dao.Salvar();
}

[/code]

Meu problema está ali na implementação desse método que me retornará o objeto criado. No caso, um objeto da Classe FuncionarioDAO.
Qual seria a forma correta de ser fazer isso? Pensei em criar um método que receba um parâmetro, no caso acima passei uma string com
o nome da classe, dentro do método faço um switch e instancio o objeto de acordo com esse parametro. Seria correto?

Agradeço a ajuda desde já.

Acho que uma solução simples para você seria passar uma Class<?> e instanciar o objeto por reflection, tipo

 IFuncionario createObject(Class<? extends IFuncionario> obj) throws InstantiationException, IllegalAccessException { return (IFuncionario) obj.newInstance();}

Agora se os construtores das classes receberem parâmetros, é legal você trabalhar cada objeto. Geralmente se tem uma fábrica de objetos para a fábrica fazer o trabalho difícil de criar objetos, mas, neste caso, esta simples, não sei se há a necessidade de uma factory.

Agradeço a ajuda Ivan, me desculpe pela ignorância mais estou iniciando em java e não compreendi a sintaxe acima.
Realmente o fabrica não seria necessária neste simples sistema, porém ela é um requisito do trabalho.

Então eu acho melhor você fazer o Java “puro”, igual é na facul…

enum TipoFuncionario{

Diretor, Merendeira, Professor;

}



IFuncionario creatObject(TipoFuncionario tipo){

    if(tipo == TipoFuncionario.Diretor){
          return(IFuncionario) new Diretor();
   } else if .....................

}

Perfeito Ivan
Funcionou belezinha aqui.
Grato pela ajuda.

bruno_SI, põe o tópico como resolvido.
Vlw

Acabei de crê. Sou nob mesmo…rsrsrs
onde marco o tópico como respondido? :lol:

Olá
Aproveitando o embalo, estava procurando na internet algo sobre Factory Method e Abstract Method aplicados com DAOs, e encontrei esse artigo:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
Porém, para a fábrica abstrata eles utilizam uma classe abstrata (que inclusive pode ser substituída por um interface), eu não queria ficar utilizando herança e pensei por trocar a classe abstrata por uma interface.

Como meu sistema é simples, não envolve muitos cadastros, tabelas etc, encontrei duas formas de implementação desses patterns com DAO.
Vou postar o código e me digam se este jeito de fazer é “feio” ou não :roll:

Fábrica abstrata (DAOFactory):

[code]package Model.DAO;

/**
*

  • @author Leandro
    */
    public interface DAOFactory {
    public BairroDAO createBairroDAO();
    public CategoriaCursoDAO createCategoriaCursoDAO();
    //… Demais assinaturas de métodos etc…
    }[/code]

Agora a fábrica concreta para DAOs utilizando persistência com JDBC (JDBCDAOFactory):

[code]package Model.DAO;

/**
*

  • @author Leandro
    */
    public class JDBCDAOFactory implements DAOFactory {

    @Override
    public BairroDAO createBairroDAO() {
    return new JDBCBairroDAO();
    }

    @Override
    public CategoriaCursoDAO createCategoriaCursoDAO() {
    return new JDBCCategoriaCursoDAO();
    }
    }[/code]

Um seletor de fábricas (um exemplo), caso se queira trabalhar com mais de um tipo de persistência (Como XML, Hibernate, etc…) (FactorySelector):

[code]package Model.DAO;

/**
*

  • @author Leandro
    /
    public final class FactorySelector {
    public enum Implementacao {
    JDBC,
    XML,
    HIBERNATE;
    }
    /
    *
    • Método para escolha da fábrica concreta.
    • @param impl Tipo de persistência a ser utilizada.
    • @return A fábrica concreta para criação dos objetos de persistência.
      */
      public static DAOFactory createDAOFactory(Implementacao impl) {
      switch(impl) {
      case JDBC:
      //Existe implementação para persistência utilizando JDBC:
      return new JDBCDAOFactory();
      case XML:
      //Não existe implementação de persistência com XML no momento.
      throw new UnsupportedOperationException(“Não há implementação para persistência com XML.”);
      case HIBERNATE:
      //Não existe implementação de persistência utilizando Hibernate no momento.
      throw new UnsupportedOperationException(“Não há implementação para persistência com Hibernate.”);
      default:
      throw new IllegalArgumentException(“Tipo de persistência desconhecida ou não suportada.”);
      }
      }
      }[/code]

Implementei desse modo tendo como modelo as práticas desse outro artigo em que a classe abstrata foi substituída por uma inteface:
http://www.javapractices.com/topic/TopicAction.do?Id=128
É a única diferença entre os dois artigos praticamente, além de algumas implementações extras.

Porém, não sei se estou errado, ou criando um anti-pattern, mas achei essa questão de criar uma DAOFactory e depois uma JDBCDAOFactory, XMLDAOFactory, ou HibernateDAOFactory, meio que reduntante, então coloquei as decisões de que implementação de DAO retornar em uma única classe, vejam:
“Fábrica única” (DAOFactoryUnica):

[code]package Model.DAO;

/**
*

  • @author Leandro
    */
    public class DAOFactoryUnica {
    public enum Implementacao {
    JDBC,
    XML,
    HIBERNATE;
    }

    public BairroDAO createBairroDAO(Implementacao impl) {
    if(impl == Implementacao.JDBC) {
    //Existe implementação para persistência utilizando JDBC:
    return new JDBCBairroDAO();
    }

     else if (impl == Implementacao.XML) {
         //Não existe implementação de persistência com XML no momento.
         throw new UnsupportedOperationException("Não há implementação para persistência com XML.");
         //Se houver implementação será:
         //return new XMLBairroDAO;
     }
     
     else if(impl == Implementacao.HIBERNATE) {
          //Não existe implementação de persistência utilizando Hibernate no momento.
          throw new UnsupportedOperationException("Não há implementação para persistência com Hibernate.");
          //Se houver implementação será:
          //return new HibernateBairroDAO;
     }
     
     else {
         throw new IllegalArgumentException("Tipo de persistência desconhecida ou não suportada.");
     }
    

    }

    public CategoriaCursoDAO createCategoriaCursoDAO(Implementacao impl) {
    if(impl == Implementacao.JDBC) {
    //Existe implementação para persistência utilizando JDBC:
    return new JDBCCategoriaCursoDAO();
    }

     else if (impl == Implementacao.XML) {
         //Não existe implementação de persistência com XML no momento.
         throw new UnsupportedOperationException("Não há implementação para persistência com XML.");
         //Se houver implementação será:
         //return new XMLCategoriaCursoDAO;
     }
     
     else if(impl == Implementacao.HIBERNATE) {
          //Não existe implementação de persistência utilizando Hibernate no momento.
          throw new UnsupportedOperationException("Não há implementação para persistência com Hibernate.");
          //Se houver implementação será:
          //return new HibernateCategoriaCursoDAO;
     }
     
     else {
         throw new IllegalArgumentException("Tipo de persistência desconhecida ou não suportada.");
     }
     
     //... Criação dos demais objetos...
    

    }
    }[/code]

Gostaria da opnião e sugestões de vocês, o que acham desse modelo, está errado, pode ser implementado e/ou melhorado?
Obrigado pessoal :slight_smile:

?? :roll:

Bom, eu não sou expert no assunto, mas, posso dizer que funcionar funciona, mas não é muito legal não, isto porque no seu lab, você tem poucas DAOs para criar, imagine em um sistema corporativo real. Além que na sua alternativa o seu código fica mais acoplado do que no outro. Pensando além, em qualidade de código, dizem que não é muito bom ter uma classe com tantas linhas rsrsrsrs… ferramentas que garantem qualidade de código reclamam de classes com muitas linhas…

É verdade amigo…
Eu repensei, aqui, não é legal mesmo implementar desse segundo modo ai, pensei que estava fazendo algo legal mas estava era fugindo da orientação a objetos e das boas práticas de programação. :oops:
Não é bom a quantidade excessiva de if’s, melhor implementar como do primeiro modo, já que o código em cada classe fica mais limpo e as responsabilidades distribuídas de uma melhor forma… :roll:
Obrigado pela dica :smiley: