Felipe,
Me desculpe, eu não prestei atenção na parte que você falou que usava Delphi. Tens meu respeito!
Não seria bem um DAO. O DAO é implementado pelo JPA (Java Persistence Framework), é ele que abstrai todo o acesso e mapeamento das entidades para tabelas do banco de dados.
Breve explicação sobre JPA
Não sei se você já deu uma olhada no JPA. É uma especificação da Oracle (um conjunto de interfaces e anotações) que você pode utilizar para fazer o mapeamento objeto-relacional de classes Java para tabelas em um banco de dados relacional (que você deve manjar bastante já).
Inclusive, ele (JPA) possui uma linguagem de query muito parecida com SQL, chamada de JP QL (Java Persistence Query Language), que pode ser utilizada para fazer queries em relação aos objetos, e não às tabelas do DB. Essas queries são em formato de String
, assim como no JDBC, o que faz com que elas tenham os mesmo problemas anteriores, como SQL Injection e problemas de queries dinâmicas. Para resolver isso, tem também um esquema bem interessante chamado de Criteria API, que te permite criar queries programáticas de uma forma bem intuitiva, sem ser em forma de strings, mas em forma de objetos que representam partes da query.
Como o JPA é só uma especificação, precisamos de alguém para implementá-la. É aqui que entram os Persistence Providers. Existem vários no mercado, mas os mais famosinhos são Hibernate, EclipseLink e OpenJPA. Eles implementam o que a especificação diz que tem que ser implementado, além de algumas funcionalidades extras (que você pode optar por utilizar, se amarrando mais àquele provider, ou não utilizar, ficando livre para trocar de um provider pra outro sem dor de cabeça).
Fim da explicação sobre JPA
Voltando. O DAO seria o objeto responsável por abstrair o acesso ao banco de dados, e, como eu falei, o JPA faz isso pra gente. Considero a classe JPAUserRepository
como uma classe de infra, pois provê funcionalidades de “plumbing”. Confesso que agora, pensando bem, também acho essa interpretação meio estranha. A classe “depende” de uma interface da camada de domínio, o que seria uma violação de que uma camada deve entender apenas as que estão abaixo dela.
Talvez eu deva considerar o JPAUserRepository como uma classe de domínio mesmo, e o JPA como a infra. Enfim, não faz muita diferença!
Olhando o sistema de perfil, podemos ver algo assim:
View -> ApplicationFacade(aqui estão os limites das transações, begin e commit) -> Domínio (entidades, repositórios) -> Infra (email, DB, requisições web, etc)
(setinha = dependência)
Repositório é um conceito da camada de domínio. DAO é um conceito da camada de Infra. Um repositório pode utilizar um DAO para buscar/persistir dados, como pode também buscar/enviar dados para outro web service, ou algo do gênero.
Você não é obrigado a utilizar o JPA como eu falei anteriormente, pode implementar o DAO você mesmo e utilizá-lo. Dentro do DAO você vai implementar as consultas SQL e utilizar a API do JDBC para abrir conexões com o banco, ou mesmo implementar alguma outra classe responsável por manter um conection pool de onde você pega as conexões.
Aquela parte do DomainStore que você citou, acho que é extremamente desnecessário querer reinventar a roda, coisa de quem gosta de sofrer (ou de aprender hehe)! Se for um projeto novo, usa JPA que é muito mais produtivo e já tem tudo pronto.
O livro do Eric Evans é sensacional, recomendo demais a leitura. Tinha muita dúvida sobre essas questões e a grande maioria delas foi sanada.