Ei! Como é o seu DAO? Ele é tão abstraído quanto o meu?

Essa é uma pergunta comum entre os desenvolvedores. Alguns acham que há uma fórmula única, que DAO é um pattern fechado e que possui seu diagrama de classes bem definido. Eu discordo.

Na minha humilde opinião, DAO é uma maneira de você encapsular o seu acesso a dados. Não importa se é através de uma factory de objetos que recebem uma Session do hibernate por injeção de dependências, ou se é um montão de métodos estáticos cheio de SQL dentro deles (argh!). Obviamente a última opção envolve diversos outros antipatterns (como singleton e métodos estáticos, que já criticamos anteriormente), porém ela consegue isolar seu acesso a dados, cumprindo o papel do DAO e de alguma maneira organizando sua camada.

Lendo a definição de Data Access Object no site da Sun, podemos chegar a um molde comum, mas nada impede que possamos incrementa-lo e modifica-lo de acordo com nossas necessidades. Por exemplo, com o Java 5, podemos tirar proveito dos generics. Na Caelum costumamos usar uma interface para os nossos DAOs parecida com a seguinte:

interface Dao<T> {
  T search(Serializable id);
  void persist(T t);
  void remove(T t);
  // ...
}

A nossa implementação de DAO genérico para hibernate fica parecida com:

class GenericHibernateDao<T> implements Dao<T> {
  private Session session;
  private Class persistentClass;
  public GenericHibernateDao(Session session, Class persistentClass) {
    this.session = session;
    this.persistentClass = persistentClass;
  }
  public T search(Serializable id) {
     return session.load(persistentClass, id);
  }
  // outros metodos da interface Dao
}

Repare que ele recebe session como argumento, que poderia ser injetada por um container. Outra opção seria buscar a session de um singleton (o clássico HibernateUtil), mas a primeira maneira é bem mais elegante e testável. Repare que ainda temos os problemas de controle de transações: onde abrimos e comitamos? dentro do Dao? de dentro do injetor de dependências? de dentro da sua lógica de negócios? Nós costumamos fazer esse controle em um interceptador ou mesmo em um Filter de servlets, dependendo do framework MVC usado. Nosso filtro é semelhante com o recomendado pela documentação do hibernate.

E então podemos utilizar nosso DAO:

Dao<Cliente> clienteDao = new GenericHibernateDao<Cliente>(session);
clienteDao.persist(cliente);
Cliente c5 = clienteDao.search(5);

Para as entidades que você precisa de mais que um simples cria/le/atualiza/deleta, criamos uma nova interface:

interface ClienteHibernateDao extends Dao<Cliente> {
   List<Cliente> buscaTodosClientesQueDevemDinheiro();
}

E teríamos uma classe ClienteHibernateDao que estende GenericHibernateDao<Cliente> e implementa ClienteDao.

Meus colegas da easytech preferem abstrair também o tipo da chave primária:

interface Dao<T, I> {
  T search(I id);
  // ...
}

Dessa maneira você realmente ganha mais tipagem, já que no DAO anterior poderíamos passar qualquer objeto serializável como chave. Podemos refinar muito mais nossas classes de acesso a dados, mas até que ponto chegar?

Ficar abstraindo demais a sua camada de persistência pode levar a proliferação de centenas de pequenas classes que simplesmente não fazem nada, só delegam e delegam. Claro que existem casos em que abstrair para apenas delegar é interessante, diminuindo o acoplamento entre suas classes, porém isso pode chegar a um ponto que vai atrapalhar o desenvolvimento.

Nesta entrada do blog dos desenvolvedores do hibernate, o uso de camadas para abstrair as ferramentas de mapeamento objeto relacional são duramente criticadas.

E você, qual é a receita de bolo para o seu DAO? Até onde você o refina?

Fonte: Caelum – Paulo Silveira

Advertisements

About Gustavo Amaro

+ Formado em Tecnologia e Análise de Sistemas + MBA em Desenvolvimento de Aplicações JAVA – SOA

Posted on 21 de Fevereiro de 2013, in Hibernate, Java, Persistência and tagged , , , , , , , , , , , . Bookmark the permalink. Deixe um comentário.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

%d bloggers like this: