FactoryDAO

11 respostas
nadilsons

Bom dia,

Implementei uma factory para camada DAO; e o tipo de retorno destas factories é uma interface IGenericDAO…
Tudo funciona bem, até que eu precisei implementar uma funcionalidade específica, cuja assinatura não existe na IGenericDAO; então para fazer uso deste método eu preciso fazer um casting… e isto está me incomodando pois eu acho que a responsabilidade do casting seria da factory, porém eu não vejo como implementar um modo da factory realizar este casting.

Alguém saberia um modo de realizar este casting na factory?
Obrigado,

Nadilson

11 Respostas

davidbuzatto

Mas sua factory já não retorna um tipo “mais abstrato”? Para que casting dentro da Factory?

Posta o código ai para a gente entender. Não entendi direito sua pergunta.

Até mais!

nadilsons

Olá davidbuzatto,

Eu sei que está difícil enteder mesmo...

Então minha factory retorna o tipo mais abstrato.... acontece que quando eu quero um método específico que eu implementei em uma classe filha, por exemplo :GerenteDAO.getComissoes(); como na interface não tenho esta assinatura... para fazer uso dele eu sou obrigado a fazer o casting...

Segue o código
public class FactoryBO implements IFactoryBO  {

    private static IFactoryBO factory = new FactoryBO();
	
    private FactoryBO() {
        //Constructor privado
    }
	
    /**
    * Implementação singleton
    */
    public static IFactoryBO getInstance() {
        return factory;
    }

    @SuppressWarnings("unchecked")
    public IBaseBO getBO(Class<? extends BaseVO> persistentClass) {
        IBaseBO<? extends BaseVO> retorno = null;

        if (persistentClass.isAnnotationPresent(BOClass.class)) {
            // Existe anotação para indicar BO específico --> Retorna BO indicado na anotação
            BOClass BOClass = (BOClass) persistentClass.getAnnotation(BOClass.class);

            try {
                retorno = BOClass.value().newInstance();

            } catch (IllegalAccessException e) {
                throw new FactoryBOException("Erro ao tentar acessar classe BO, " + e.getMessage());

            } catch (InstantiationException e) {
                throw new FactoryBOException("Erro ao tentar instanciar classe BO, " + e.getMessage());
            }

        } else {
            // Se não existir anotação para indicar BO específico --> Retorna BO Padrão
            retorno = new BaseBO();
        }
		
        //Seta a classe persistente no objeto BO 
        retorno.setPersistentClass(persistentClass);
		
        return retorno;
    }
}

Obrigado

rodrigo_ctba

De uma olhada nesse tópico

http://www.hibernate.org/328.html

É um tutorial para criar GenericDAO com o Hibernate.

Com base nesse exemplo consegui fazer um Generec para JDBC.

Qualquer coisa avisa !!!

t+

Abdon

eu sou contra daos genericos por este e outros motivos, a solução que eu utilizaria para manter um baixo acoplamento entre sua camada percistente e o resto do sistema, em outras palavras para vc não fazer um cast de um tipo concerto, seria definir outra interface, que implemente os metodos adicionais, o local que vc for utilizar, faça o cast para a interface nova, não para o tipo concreto.

marcelo_mococa

construir um GenericDao parecido com o do Hibernate com JDBC é um pouco complicado.

Sobre o casting, não vejo problema algum desde que seja para outra interface.

nadilsons

Você não utiliza dao genéricos? O que você propõe então?

Obrigado,

nadilsons

Então, mas eu estou tentando pensar em um modo que a outra camada nao precise fazer o casting…

Abdon

eu proponho o contrario do que vc quer: um dao para cada entidade, e cast do lado de quem vai utilizar. Isso para evitar o tipo de problema que vc esta tendo, não tem problema em fazer um cast do lado que vc vai utilizar desde que ele seja feito para uma interface, claro que é possivel evitar este cast fazendo um DAO parametrizado. ele ficaria tipo assim:

class FactoryDAO&lt;E extends Objetc&gt;  

public E getInstance(){
    return e.newInstance();
}

Não sei se é exatamente assim que se codifica pois eu não estou acostumado a codificar este tipo de coisa, mais é bem simples, a idéia é esta.
So funfa com java &gt= 5,0

nadilsons
eu proponho o contrario do que vc quer: um dao para cada entidade,

Bem, mas quando você utiliza frameworks ORM como o hibernate, a necessidade de um DAO para cada entidade é QUASE nula… mas entendo o seu ponto de vista e acho totalmente justificável apesar de preferir um abordagem mais generica;

Muito obrigado pela sua ajuda… vou tentar utilizar o código que vc postou.

sergiotaborda

nadilsons:
Bom dia,

Implementei uma factory para camada DAO; e o tipo de retorno destas factories é uma interface IGenericDAO…
Tudo funciona bem, até que eu precisei implementar uma funcionalidade específica, cuja assinatura não existe na IGenericDAO; então para fazer uso deste método eu preciso fazer um casting… e isto está me incomodando pois eu acho que a responsabilidade do casting seria da factory, porém eu não vejo como implementar um modo da factory realizar este casting.

Alguém saberia um modo de realizar este casting na factory?

O cast não é tão ruim assim. Desde que vc faça cast de interfaces, é claro. Mas isso é assumir que o usuário da fábrica sabe demais sobre o que a fábrica produz. Isso é errado ? Não completamente, afinal, vc sabe o que uma fábrica de carros (dao) fabrica inclusive os modelos (dao simples, dao extentido) que ela fabrica
Mas como vc sabe sobre os modelos ? Porque a fábrica lhe informa ou porque vc analiza o que sai dela ?
Fazer cast é equivalente a analizar o que sai dela. Ter um método para cada tipo de produto equivale à fabrica informar o que sabe fazer.

Se vc não quer o cast, a solução é obviamente ter um método para cada tipo de dao. Ou em alternativa ter um método genérico, mais ou menos assim:

public <T extends DAO> T getDAO(Class<T> daoClass){
       if (daoClass.equals(ExtendedDAO.class)){
            return new AdvancedDAO ()
       } else {
           return new DefaultDAO ();
       }
}

Uma alternativa seria simplesmente incluir os metodos extra na interface do DAO. Assim fica com apenas um tipo e é mais simples. Quando os métodos não poderem ser usado, simplesmente lance uma UnsupportedOperationException. E deixe claro no javadoc qual método pode ser chamado quando. Este mecanismo é usado pelo Java Collection Framework e funciona. O problema é que esconde a informação até ao momento em que vc executa o codigo, obrigando a ler muito bem o javadoc. No caso do JCF isso faz sentido, no caso de uma fabrica de daos tlv não faça.

Finalmente, uma fabrica de daos é um DAOFactory e não um FactoryDAO (que seria um DAO para objectos do tipo Factory. Compare com ClienteDAO)

nadilsons

Olá sergiotaborda,

Sua mensagem me ajudou bastate!!

Realmente estou começando a pensar que o cast nao é tao ruim… e seja realmente necessário… mudei um pouco a modelagem para fazer com cast.

Entendo que desta forma não seria a melhor escolha… acho q não faz muito sentido para uma fábrica de DAOs

Realmente… rs; muito obrigado pela elucidação, vou corrigir os fontes.

Mais uma vez, obrigado.

Criado 3 de agosto de 2007
Ultima resposta 3 de ago. de 2007
Respostas 11
Participantes 6