DAO - ORM - Business logic

Amigos, este tópico não é uma dúvida, é um levantamento de uma discussão.

Recentemente tenho lido vários artigos sobre DAO - ORM - BUSINESS LOGIC no padrão MVC.
Desde antes da existência do Hibernate eu já implementava lógicas baseadas em Dao’s para as minhas Entidades.

Andei lendo alguns materiais sobre descarte da camada Dao porque dizem que “o Hibernate é seu dao”.
Tentei seriamente seguir esse tipo de conceito, onde o meu ORM estaria mais entrelaçado com a lógica de negócios e o resultado foi catastrófico. Tivemos que refatorar muitas linhas de código para separar uma camada Dao, para que pudéssemos encapsular as regras de persistência.

Daí então encontrei um pequeno problema, algumas consultas advém de regras de negócio, elas estão, muitas vezes, diretamente ligadas à camada de persistência.
Pensando nisso resolvi retornar objetos Criteria para a as regras de negócios. Até o momento não precisei remoldar a camada de persistência, pois confio no Hibernate. Porém se um dia eu quiser abstrair o Hibernate vou ter que refatorar toda a regra de negócio novamente.

Sou a favor da separação das regras de negócio das regras de persistência. E vocês, o que opinam em relação a isso?

[quote=doravan]Amigos, este tópico não é uma dúvida, é um levantamento de uma discussão.

Recentemente tenho lido vários artigos sobre DAO - ORM - BUSINESS LOGIC no padrão MVC.
Desde antes da existência do Hibernate eu já implementava lógicas baseadas em Dao’s para as minhas Entidades.
[/quote]
Antes de mais nada, vale dizer que DAO, ORM, nem nada ligado a persistencia, nao se relaciona, nem de longe ao padrao MVC.

Sim, ha quem diga isso. Mas mesmo os que dizem isso nao aconselham entrelacar acesso ao banco com regra de negocio. O que eles dizem (as vezes com razao) eh que eu nao preciso de uma camada extra para simplesmente delegar o trabalho a um entityManager/session. Por exemplo:

public class ClienteDAO{
  public void salvar(Cliente cliente){
     entityManages.save(cliente)
  }
}

Nesse caso porque eu nao chamo diretamente entityManager.save(cliente)?

Mas isto nao quer dizer que eu espalhar o entityManager pelas entidades.

Ainda prefiro uma camada para isso. De uma olhada no padrao repositorio do Domain Driven Design. Tem uma diferenca sutil em relacao ao DAO (embora a implementacao seja quase igual). Eles fazem parte da regra de negocio, mas funcionam como uma fachada para abstrair o armazenamento (repositorio) dos objetos.

Sempre, regras de negocio e acesso a dados nao podem ser misturadas, nem nunca ninguem indicou o contrario. As entidades nao devem se preocupar com como serao gravadas ou trazidas de um banco de dados. Exceto quando isso eh feito de forma transparente e nao intrusiva, como no rails/grails.

Por favor, não poste tópicos usando apenas LETRAS MAIÚSCULAS no título, ou no corpo do tópico.

Também sou do princípio de que uma camada DAO é desnecessária se sua única função é delegar as chamadas de métodos à unidade de persistência. A partir do momento que você realmente precisa de algo entre a unidade de persistência e sua camada superior (ou se no início de um projeto já for notada essa necessidade), aí sim os DAOs podem entrar em cena.

Eu pelo menos nunca vi um caso desses em que não houvesse necessidade de uma camada intermediária acima do ORM. No máximo, descartavam-se as DAOs e utilizava-se apenas as Services (no caso quando é usado o framework Spring).

Também tem os que dizem que o padrão DAO está morto, que o mais apropriado é o padrão Repository, que foi citado pelo YvGa. Nesse caso não posso opinar porque nunca cheguei a utilizar este padrão, mas creio que seja válido.

[quote=doravan]Amigos, este tópico não é uma dúvida, é um levantamento de uma discussão.

Recentemente tenho lido vários artigos sobre DAO - ORM - BUSINESS LOGIC no padrão MVC.
Desde antes da existência do Hibernate eu já implementava lógicas baseadas em Dao’s para as minhas Entidades.

Andei lendo alguns materiais sobre descarte da camada Dao porque dizem que “o Hibernate é seu dao”.
Tentei seriamente seguir esse tipo de conceito, onde o meu ORM estaria mais entrelaçado com a lógica de negócios e o resultado foi catastrófico. Tivemos que refatorar muitas linhas de código para separar uma camada Dao, para que pudéssemos encapsular as regras de persistência.

Daí então encontrei um pequeno problema, algumas consultas advém de regras de negócio, elas estão, muitas vezes, diretamente ligadas à camada de persistência.
Pensando nisso resolvi retornar objetos Criteria para a as regras de negócios. Até o momento não precisei remoldar a camada de persistência, pois confio no Hibernate. Porém se um dia eu quiser abstrair o Hibernate vou ter que refatorar toda a regra de negócio novamente.

Sou a favor da separação das regras de negócio das regras de persistência. E vocês, o que opinam em relação a isso?

[/quote]

Realmente vc precisa esquecer os DAOs. Isso é coisa do século passado e EJB 2.1

O que você procura é uma arquitetura com DomainStore, repositorio e query Object

O Hibernate ou o JPA já são implementações do DomainStore (procure Core JEE Patterns 2) e o DAO já morreu. Não é sensato encapsular o DomainStore no num bando de DAOs. Isso é andar para trás.

Mas realmente vc precisa de um objeto que sabe montar as pesquisas. Este papel podia ser do dao nos tempos antigos, mas agora cabe ao Repositorio.
O repositório tem acesso a um DomainStore para invocar as pesquisas, mas pode fazer pesquisa de qualquer outra fonte , como arquivos e webservices.
O repositorio pode ainda acumular a responsabilidade de edição do domaistore (save, delete, etc…) embora isso seja opcional e existem outras formas usando Services.

A chamadas “logicas de negocio” não existem apenas em um andar, embora existam certos objetos que associamos diretamente a elas como validatores e services. Vc tem razão que a criação de consultas e execução de pesquisas no banco faz parte dessa logica de negocio. Agora, isso não significa que toda a logica de negocio tenha que ficar em objetos do mesmo tipo.

Por outro lado DAO-ORM-Business Logic não é o padrão MVC e o padrão MVC não se pode aplicar dessa forma. Ai também, vc tem um problema conceptual. MNV não é separação em camadas e você precisa realmente entender como se separa as camadas e por quê.

Nãoooooooooooooo. Vc precisa esquecer o ORM e abracar os DAOs. Só porque a grande maioria diz que ORM é necessário e maravilhoso, não significa que isso seja verdade…

http://www.guj.com.br/java/252013-voce-nao-gosta-do-hibernate-eu-tb-nao-leia-para-entender-o-porque/

[quote=saoj]Nãoooooooooooooo. Vc precisa esquecer o ORM e abracar os DAOs. Só porque a grande maioria diz que ORM é necessário e maravilhoso, não significa que isso seja verdade…

http://www.guj.com.br/java/252013-voce-nao-gosta-do-hibernate-eu-tb-nao-leia-para-entender-o-porque/

Eu nunca trabalhei com o IBatis, nem com o MentaBean, nao posso falar.

O que eu posso falar eh JDBC puro nem a pau!!

Se eu tenho um modelo OO eu vou ter que cuidar manualmente de toda a estrutura de relacionamentos, mapear o que eh chave estrangeira, para composicao de objetos, mapear heranca quando for o caso, cuidar na mao de todas as situacoes, verificar se uma propriedade eh nula ou nao e instancia-la se for o caso. Verificar se preciso ou nao em determinado trazer um relacionamento ou nao. Sem chance!!!

Se voce nao tem um modelo de objetos, ou se seus objetos nao passam de representacoes simples de um registro do banco em memoria, esqueca ORM, voce nao precisa deles. Se voce tem um modelo de dominio rico, com entidades inteligentes, que representam bem o dominio, com composicoes bem feitas. Entao, infelizmente, voce precisa de um ORM.

A grande praga eh que muita gente acha que ORM serve pra popular objetos e “fazer insert”. Alem de que, de todo mundo que vejo falar mal do Hibernate usa o fato de os desenvolvedores nao quererem/saberem usar SQL. Mas quem usa o Hibernate tem que saber SQL, ou vai ficar tateando no escuro em qualquer problema.

Se voce me perguntar se eu gosto do Hibernate, a resposta eh Nao! Mas a opcao a ele eh nao usar banco relacional, coisa que ainda nao eh viavel para a maioria das aplicacoes. Ao menos eh o que pensam os que tem o poder de decisao (dinheiro) sobre a arquitetura.

Cara, concordo com você, eu acho que toda escolha de tecnologia tem sempre a palavra “depende”.

Vejo conforme falou, com relação à camada de objetos, não se justifica usar Hibernate apenas para representar tabelas como objetos do Java…