Dúvida DAO

Olá a todos,
tenho uma aplicação onde eu tenho 2 classes, e para
cada classe tenho um DAO, onde faço a conexão com o

hibernate, carrego todas as classes para o hibernate e
realizo as 4 operações básicas (CRUD).
Vejo que há uma repetição de código para cada DAO,
é praticamente o mesmo código, e em cada DAO carrego
todas as classes do sistema, pois todas se relacionam.
Atualmente o sistema possui apenas 2 classes, mas irá
crescer.
Gostaria de saber se há alguma solução para evitar
essa repetição?
Atenciosamente,
Viviane Grieco

Sim!! Há!
Crie uma interface DAO, que apenas vai ditar o comportamento de um DAO para seu sistema. Mais ou menos assim:

public interface DAO{

    public boolean insert(Object o);
    public boolean delete(Object o);
    public boolean update(Object o);
    public Object load(Object pk);
    public java.util.List loadAll();

}

E depois uma classe abstrata que implementa alguns comportamentos que são comuns a todos os seus DAOs.

public abstract class MyHibernateDAO implements DAO{

    public boolean insert(Object o){
        //.. implementa o código mais genérico possível de inserção
    }
    // idem para delete e update ...
}

E pronto. :wink:

Só um comentário: estou lendo o Effective Java [ótimo livro, a propósito] e o Bloch sugere um padrão destas classes abstratas que servem para os métodos de interface, chamando semrpe de Abstract<NOMEDAINTERFACE> .

Não sei até que ponto sito é interessante [isto é um fórum de discussão: DISCUTAM!!], mas acho bem legal este tipo de coisa, e inclusive é muito utilizado ans APIs do core. Até no AbstractPrevalentSystem rola…

[]s

É. De fato existe esta nomenclatura, Phillip.
Então,

public abstract class AbstractHibernateDAO implements DAO&#123;

   //a mesma lenga-lenga...

&#125;

:wink:

Nao entendi a necessidade da criacao da interface DAO descrita pelo Daniel. Acho ela meio Useless, ja que a classe abstrata parece ser exatamente igual a a interface.
Sei da importancia de programar para interfaces, mas acho que as vezes esse conceito eh levado um pouco ao extremo. Neste caso em especifico, por exemplo, acho perfeitamente dispensavel essa interface DAO.
Muitas vezes a criacao de classes abstratas me parece mais razoavel que o uso de interfaces propriamente dita.

[quote=“tanque”]Nao entendi a necessidade da criacao da interface DAO descrita pelo Daniel. Acho ela meio Useless, ja que a classe abstrata parece ser exatamente igual a a interface.
Sei da importancia de programar para interfaces, mas acho que as vezes esse conceito eh levado um pouco ao extremo. Neste caso em especifico, por exemplo, acho perfeitamente dispensavel essa interface DAO.
Muitas vezes a criacao de classes abstratas me parece mais razoavel que o uso de interfaces propriamente dita.[/quote]

A idéia daquela interface é dizer que a manipulação de dados deve ser feita da mesma forma, independentemente da forma como os dados estão organizados/armazenados. Agora, imagine que você TAMBÉM tenha que manipular dados em, hmmmm…, arquivos CSV. Então você faria:

public abstract class AbstractCSVDAO implements DAO&#123;

   //bla bla bla

&#125;

Criaria uma implementação para um certo tipo de CSV:

public class UseCSVDAO extends AbstractCSVDAO&#123;

    // implementa sua lógica aqui...

&#125;

E instanciaria assim:

//...
DAO dao = DAOContainer.getInstance&#40;&#41;.create&#40;com.acme.AbstractCSVDAO.class&#41;;
List list = dao.loadAll&#40;&#41;;
Iterator i = list.iterator&#40;&#41;;
dao = DAOContainer.getInstance&#40;&#41;.create&#40;com.acme.AbstractHibernateDAO.class&#41;;
while&#40;i.hasNext&#40;&#41;&#41;&#123;
       User u = &#40;User&#41;i.next&#40;&#41;;
       dao.insert&#40;u&#41;;        
&#125;

No código acima, eu usei um pseudo-IoCContainer para instanciar meus DAOs e fiquei trabalhando sobre o comportamento deles (a interface), não sobre a implementação (as classes). E é isso.

Poxa, relendo tudo isso, achei que não ficou NADA claro a explicação que eu dei. Mas, enfim, a idéia da interface é “apenas” dizer que todo mundo no seu sistema que fizer manipulação de dados sobre algum tipo de fonte deve implementar aquele comportamento. SÓ.

p.s.: Também não gostei do lance do pseudo-IoC Container. Ficou tosquinho :frowning:

[quote=“tanque”]Nao entendi a necessidade da criacao da interface DAO descrita pelo Daniel. Acho ela meio Useless, ja que a classe abstrata parece ser exatamente igual a a interface.
Sei da importancia de programar para interfaces, mas acho que as vezes esse conceito eh levado um pouco ao extremo. Neste caso em especifico, por exemplo, acho perfeitamente dispensavel essa interface DAO.
Muitas vezes a criacao de classes abstratas me parece mais razoavel que o uso de interfaces propriamente dita.[/quote]

Bom, vamos lá. Note que estou bem influenciado pelo Effective Java :wink:

Como Java não permite herança múltipla, cabe às interfaces proprocionar uma mistura de tipos em uma classe, adicionando um tipo ao “tipo primário dela”. Se você dependesse da classe abstrata, como poderia fazer seu DAO pertencer a uma outra hierarquia?

Isso pode ser necessário ou não, para prover um mecanismo eficiente para ambos os casos, você pode criar uma interface que é o que realmente conta na hora de chamar métodos na classe, e pode prover uma Abstract<nome da interface> para prover as cosias já “mastigadas” para um DAO que não precisa herdar nada.

Acho que consegui ser mais confuso que o Daniel, mas imagina que vocês tem dois tipos de classes, que precisam ser persistidos em dois lugares diferentes.

Uma classe, você persiste num SGBD, logo você pode estender um AbstractDao que te server perfeitamente.

A outra precisa ser persistida em algo exótico, como o Prevayler. Você precisa que seu DAO pertença a uma hierarquia definida, ou seja: além de ser um DAO, ele precisa estender uma classe qualquer para funcionar. A suloção é estender a classe necessária e implementar a interface.

Vanessa Sabino tem um resumo bem legal do Effective Java no site dela, em português, este item específico você encotnra em http://vanessas.sites.uol.com.br/java/ej3.html , o blog (com o resumo completo) fica em http://java.blogger.com.br

[]s

Kct, esqueci de dizer uma coisa:

Geralmente, quando trabalhando com persistência onde é aplicável uma linguagem de consulta diretamente à camada [SQL, pore exemplo] eu colocaria outras duas interfaces:

public interface DAO&#123;

    public boolean insert&#40;Object o&#41;;
    public boolean delete&#40;Object o&#41;;
    public boolean update&#40;Object o&#41;;
    public Object load&#40;Object pk&#41;;
    public java.util.List loadAll&#40;&#41;;

    public java.util.List filter&#40;Object f&#41;;
    public int updateFiltered&#40;Object o, Object f&#41;;
&#125; 

No émtodo filter, você passa algo [como uma String] uqe, no caso específico de SQL, seria colocado no WHERE [cuidado com acoplamento!! evite usar sintaxe SQL diretamente], no update, os dados nos objetos que obedeçam ao filtro definido por f [no mesmo esquema do filter()] seria atualizados para os dados de o [como em update()].

[]s