Boa noite,
Eu estou com problemas para compreender esses três padrões, neste site http://www.javabuilding.com/architecture/arquitetura-com-domainstore-repositorio-e-query-object.html?page=1 é mostrado a interface DomainStore e a classe AbstractRepository, mas onde eu implemento a persistência? Pelo que eu entendi no repositório é onde vai minha lógica de negócio, ou seja, a implementação das minhas pesquisas específicas, mas onde vai a implementação do metodo save()?
Pelo que eu entendi lendo os comentários desse blog https://sergiotaborda.wordpress.com/desenvolvimento-de-software/java/do-dao-ao-domain-store/ em especial o comentário do Daniel Bussade do dia 2008/05/08 às 18:31 juntamente com a reposta do meu xará , o blog da caelum http://blog.caelum.com.br/possibilidades-de-design-no-uso-do-seu-generic-dao/ e este outro blog http://www.rponte.com.br/2009/06/08/no-more-daos/ de alguma forma eu esta usando estes padrões (DomainStore, Repository e Query Object) inconscientemente. Porque normalmente eu crio da seguinte maneira:[/quote]
public interface Dao<T, I> {} //Um CRUD simples save (T t), delete(T t), getById(I id) e getAll()
public abstract class AbstractDao<T, I> implements Dao<T, I> {} //Aqui eu faço a implementação para meu ORM (Hibernate)
public interface EstadoDao extends Dao<Estado, Long>{} //Aqui eu coloco somente buscas especificas. Ex: produzMelhorCafe();
public class EstadoDaoImpl extends AbstractDao<Estado, Long> implements EstadoDao {} //Aqui eu faço a implementação das buscas.
public class Estado implements Serializable {} // A entidade Estado
Eu também dei uma lida nestes sites:
http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/
http://www.guj.com.br/java/249971-padrao-repository
http://www.guj.com.br/java/289087-repository–dao/2
http://www.guj.com.br/37279-dao-vs-repository-pattern
http://www.guj.com.br/java/125666-repository-exemplo-pratico
http://www.guj.com.br/java/231647-opinioes-implementacao-do-padrao-repository
http://www.guj.com.br/java/74015-diferenca-entre-repository-e-dao
Mas ainda sim tá difícil entender. Alguém poderia me dar um exemplo usando meu exemplo acima?
PS: Tive que desabilitar os links no texto por que não tava conseguindo formatar.
De forma simples :
O repositório é quem define as queries e monta os objetos que são devolvidos à camada de cima.
As queries são montadas em uma forma agnóstica ao mecanismo de persistencia usando um Query Object.
O Domain Store executa as queries e devolve os objetos. Se os objetos devolvidos pelo domain store já são os que o respositorio vai devolver então é só dar return. Caso contrário o repositorio monta o objeto de saida com base no objeto reecebido do domainStore
É importante que o Repositório seja isolado da tecnologia do DomainStore porque o DomainStore fica na camada de persistencia e o repositorio na camada de dominio.
O repositorio está na camada de dominio/negócio porque as queries em si mesmas representam regras de negócio. Se as relações entre as entidades mudarem as queries também têm que mudar. As queries refletem regras de dominio.
A implementação do DomainStore é tecnologica. Em tese pode ser um HashMap de HashMaps na memória e isto é util para testes unitários ,por exemplo.
Na prática o DomainStore será implementado usando Hibernate ou JPA ou qualquer coisa nesse estilo. Normalmente associado ao conceito de DomainStore ha o conceito de Metamodelo de dominio que essas ferramentas já cria baseando-se em anotações ou xml. Mas pode ser que para queires avançadas você queira misturar outras ferramentas ou fazer as queries mais no JDBC. De qualquer forma o DomainStore irá esconder isso para você. Não as queries , mas a forma como elas são executadas.
O Hibernate tem a sua Criteria que são Queryobjects, mas o seu repositório não deveria usar diretamente estes objetos. Ele deveria ter uma estrutrua de query object independente do hibernate que depois a implementação do DomainStore que usa hibernate vai traduzir esse objeto seu para os criterias dele. Assim, sempre ha um desacoplamento entre as duas camadas e vc pode trocar por uma implementação do DomainStore que use outra tecnologia sem ter que mudar as queries que já escreveu. Mudar estas queries é ruim porque representam regras de dominio que vc não quer reescrever e retestar …
Os métodos de save e delete são especiais. Eles são implementados pelo DomainStore. No exemplo do site eu coloquei os repositorios intermediando a chamada porque conceptualmente o domainstore pode usar objetos diferentes daqueles que o dominio usa. Então o Repositorio teria que converter de uns para os outros. Mas no fim, a operação de save em si é basicamente uma chamada de tecnologia que visa gravar o objeto em algum lugar possivelmente gerando uma chave para ele e devolver.
No caso do Hibernate apenas o DomainStore deve mexer com o objeto Session que está asociado à transação. O repositorio não precisa se preocupar com isto (da mesma forma que um serviço também não se preocuparia.
O método Save do repositorio deve ser chamado por um método de algum serviço. O serviço é que é responsável por validar e garantir que o objeto prestes a ser salvo é correto e válido. O repositorio então só media a transformação desses para objetos do domainstore que por sua vez os grava
Em relação ao uso de DAO com Hibernate, como já disse várias vezes aqui e no meu blog é uma abominação. Repositorios não são DAOs e vice versa. O hibernate por exemplo, já encapsula os DAO para vc na forma de dialectos especializados para cada banco de dados. DAOs não fazem parte da camada de dominio e si da de persistencia e isso é o problema porque obrigam suas queries a serem escritas na forma relativa ao banco e ao sql e não ao dominio. Repositorios são objetos do dominio (como os serviços) e não falam “SQL”, falam “Objeto”
Espero ter esclarecido melhor.
Vc não teria algum exemplo em código ou um diagrama (classe ou sequencia para eu entender melhor)?
Vlw