Respostas:
DAO
é uma abstração da persistência de dados .
Repository
é uma abstração de uma coleção de objetos .
DAO
seria considerado mais próximo do banco de dados, geralmente centrado na tabela.
Repository
seria considerado mais próximo do domínio, lidando apenas com raízes agregadas.
Repository
poderia ser implementado usando DAO
's, mas você não faria o contrário.
Além disso, a Repository
geralmente é uma interface mais estreita. Deve ser simplesmente uma coleção de objetos, com Get(id)
, Find(ISpecification)
, Add(Entity)
.
Um método como Update
é apropriado em uma DAO
, mas não em uma Repository
- ao usar a Repository
, as alterações nas entidades geralmente seriam rastreadas por UnitOfWork separado.
Parece comum ver implementações chamadas a Repository
que são realmente mais a DAO
, e, portanto, acho que há alguma confusão sobre a diferença entre elas.
OK, acho que posso explicar melhor o que coloquei nos comentários :). Portanto, basicamente, você pode ver os dois iguais, embora o DAO seja um padrão mais flexível que o Repositório. Se você quiser usar os dois, use o Repositório em seus DAO-s. Vou explicar cada um deles abaixo:
É um repositório de um tipo específico de objetos - permite pesquisar um tipo específico de objetos e armazená-los. Normalmente, ele só lida com um tipo de objeto. Por exemplo AppleRepository
, permitiria que você faça AppleRepository.findAll(criteria)
ou AppleRepository.save(juicyApple)
. Observe que o Repositório está usando termos do Modelo de Domínio (não termos do banco de dados - nada relacionado a como os dados são mantidos em qualquer lugar).
Um repositório provavelmente armazenará todos os dados na mesma tabela, enquanto o padrão não exige isso. O fato de ele manipular apenas um tipo de dados, porém, o faz logicamente conectado a uma tabela principal (se usada para persistência do banco de dados).
Um DAO é uma classe que localiza dados para você (é principalmente um localizador, mas é comumente usado para também armazenar os dados). O padrão não restringe o armazenamento de dados do mesmo tipo, portanto, você pode facilmente ter um DAO que localiza / armazena objetos relacionados.
Por exemplo, você pode facilmente ter o UserDao que expõe métodos como
Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)
Todos esses estão relacionados ao Usuário (e segurança) e podem ser especificados no mesmo DAO. Este não é o caso do Repositório.
Observe que os dois padrões realmente significam o mesmo (eles armazenam dados e abstraem o acesso a eles, e ambos são expressos mais perto do modelo de domínio e quase não contêm nenhuma referência ao banco de dados), mas a maneira como são usados pode ser um pouco diferente, sendo o DAO um pouco mais flexível / genérico, enquanto o Repositório é um pouco mais específico e restritivo apenas a um tipo.
CarDescription
com, por exemplo, language_id
como chave estrangeira - então, para recuperar que devo fazer algo assim: o CarRepository.getAll(new Criteria(carOwner.id, language.id));
que me daria todos os carros de um idioma em um idioma específico - é o caminho certo para fazê-lo ?
CarRepository.findByLanguageId(language.id)
e você nem precisa escrever o código, basta definir a interface com um método com esse nome e o Spring Data cuida da criação da implementação de classe padrão para você. Coisas muito legais;) #
findById
). E você está praticamente pronto. O que o Spring Data faz é encontrar todas essas interfaces que você criou, que estendem a interface do Repositório e criam as classes para você. Você nunca verá essas classes e não poderá criar novas instâncias, mas não precisa, pois pode conectar a interface automaticamente e deixar o Spring localizar esse objeto de repositório.
O DAO e o padrão do repositório são formas de implementar o Data Access Layer (DAL). Então, vamos começar com o DAL, primeiro.
Os aplicativos orientados a objetos que acessam um banco de dados devem ter alguma lógica para lidar com o acesso ao banco de dados. Para manter o código limpo e modular, recomenda-se que a lógica de acesso ao banco de dados seja isolada em um módulo separado. Na arquitetura em camadas, este módulo é DAL.
Até o momento, não falamos sobre nenhuma implementação específica: apenas um princípio geral que coloca a lógica de acesso ao banco de dados em um módulo separado.
Agora, como podemos implementar esse princípio? Bem, uma maneira conhecida de implementar isso, em particular com estruturas como o Hibernate, é o padrão DAO.
O padrão DAO é uma maneira de gerar DAL, onde normalmente, cada entidade de domínio tem seu próprio DAO. Por exemplo, User
e UserDao
,Appointment
e AppointmentDao
, etc. Um exemplo de DAO com Hibernate: http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .
Então, o que é padrão de repositório? Como o DAO, o padrão do repositório também é uma maneira de obter o DAL. O ponto principal no padrão de repositório é que, da perspectiva do cliente / usuário, ele deve parecer ou se comportar como uma coleção. O que se entende por se comportar como uma coleção não é que ela precise ser instanciada Collection collection = new SomeCollection()
. Em vez disso, significa que ele deve oferecer suporte a operações como adicionar, remover, conter etc. Essa é a essência do padrão do Repositório.
Na prática, por exemplo, no caso de usar o Hibernate, o padrão do Repositório é realizado com o DAO. Essa é uma instância do DAL e pode ser ao mesmo tempo uma instância do padrão DAO e do padrão Repository.
O padrão de repositório não é necessariamente algo que se constrói sobre o DAO (como alguns podem sugerir). Se os DAOs forem projetados com uma interface que suporte as operações mencionadas acima, será uma instância do padrão de Repositório. Pense nisso: se os DAOs já fornecem um conjunto de operações semelhantes a coleções, então qual é a necessidade de uma camada extra sobre ela?
Francamente, isso parece uma distinção semântica, não uma distinção técnica. A frase Objeto de Acesso a Dados não se refere a um "banco de dados". E, embora você possa projetá-lo para ser centrado no banco de dados, acho que a maioria das pessoas consideraria isso uma falha de design.
O objetivo do DAO é ocultar os detalhes de implementação do mecanismo de acesso a dados. Como o padrão do Repositório é diferente? Tanto quanto eu posso dizer, não é. Dizer um Repositório é diferente de um DAO porque você está lidando com / retorna uma coleção de objetos não pode estar certo; Os DAOs também podem retornar coleções de objetos.
Tudo o que li sobre o padrão de repositório parece depender dessa distinção: design ruim do DAO versus bom design do DAO (também conhecido como padrão de design do repositório).
Repositório é um termo mais abstrato orientado ao domínio que faz parte do Design Orientado a Domínio, faz parte do design de domínio e é uma linguagem comum; o DAO é uma abstração técnica para a tecnologia de acesso a dados; o repositório se preocupa apenas com o gerenciamento de dados e fábricas existentes para a criação de dados.
verifique estes links:
http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html
A principal diferença é que um repositório lida com o acesso às raízes agregadas de forma agregada, enquanto o DAO lida com o acesso às entidades. Portanto, é comum que um repositório delegue a persistência real das raízes agregadas a um DAO. Além disso, como a raiz agregada deve manipular o acesso de outras entidades, pode ser necessário delegar esse acesso a outros DAOs.
O DAO fornece abstração em arquivos de banco de dados / dados ou qualquer outro mecanismo de persistência para que a camada de persistência possa ser manipulada sem conhecer os detalhes da implementação.
Enquanto nas classes Repository, várias classes DAO podem ser usadas dentro de um único método Repository para executar uma operação da "perspectiva do aplicativo". Portanto, em vez de usar vários DAO na camada Domínio, use o repositório para fazer isso. Repositório é uma camada que pode conter alguma lógica de aplicativo como: Se os dados estiverem disponíveis no cache da memória, busque-os no cache, caso contrário, busque dados da rede e armazene-os no cache da memória para recuperação na próxima vez.
O repositório nada mais é que um DAO bem projetado.
O ORM é centralizado na tabela, mas não o DAO.
Não há necessidade de usar vários DAO no repositório, pois o DAO em si pode fazer exatamente o mesmo com repositórios / entidades ORM ou qualquer provedor DAL, não importa onde e como um carro seja persistido 1 tabela, 2 tabelas, n tabelas, meia tabela, uma serviço da web, uma tabela e um serviço da web etc. Os serviços usam vários DAO / repositórios.
Meu próprio DAO, digamos que o CarDao lide apenas com o DTO do carro, quero dizer, apenas leve o DTO do carro na entrada e retorne apenas as coleções de DTO do carro ou DTO do carro na saída.
Portanto, assim como o Repositório, o DAO na verdade é uma IoC, para a lógica de negócios, permitindo que as interfaces de persitência não sejam intimidadas por estratégias ou legados de persitência. O DAO encapsula a estratégia de persistência e fornece a interface de persistência relacionada ao domínio. Repositório é apenas mais uma palavra para aqueles que não entenderam o que era realmente um DAO bem definido.
Tente descobrir se o DAO ou o padrão de repositório é mais aplicável à seguinte situação: Imagine que você gostaria de fornecer uma API de acesso a dados uniforme para um mecanismo persistente para vários tipos de fontes de dados, como repositórios RDBMS, LDAP, OODB, XML e arquivos simples.
Consulte também os seguintes links, se estiver interessado:
http://www.codeinsanity.com/2008/08/repository-pattern.html
http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/
http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx
em uma frase muito simples: a diferença significativa é que os Repositórios representam coleções, enquanto os DAOs estão mais próximos do banco de dados, geralmente muito mais centrados em tabelas.
Na estrutura da primavera, há uma anotação chamada repositório e, na descrição desta anotação, há informações úteis sobre o repositório, que eu acho que são úteis para esta discussão.
Indica que uma classe anotada é um "Repositório", originalmente definido por Domain-Driven Design (Evans, 2003) como "um mecanismo para encapsular o comportamento de armazenamento, recuperação e pesquisa que emula uma coleção de objetos".
As equipes que implementam padrões tradicionais Java EE como "Data Access Object" também podem aplicar esse estereótipo às classes DAO, embora seja necessário ter cuidado para entender a distinção entre o Data Access Object e os repositórios no estilo DDD antes de fazê-lo. Essa anotação é um estereótipo de uso geral e as equipes individuais podem restringir sua semântica e usá-las conforme apropriado.
Uma classe assim anotada é elegível para tradução Spring DataAccessException quando usada em conjunto com um PersistenceExceptionTranslationPostProcessor. A classe anotada também é esclarecida quanto ao seu papel na arquitetura geral do aplicativo para fins de ferramentas, aspectos etc.
IRepository
interface. Você deseja que seu repositório use DAOs em sua implementação. Lembre-se, um DAO será um objeto por tabela, enquanto um Repositório quase sempre precisará usar vários DAOs para criar uma única Entidade. Se você achar que não é esse o caso, que seu Repositório e Entidade precisam acessar apenas uma única tabela, provavelmente você está criando um domínio anêmico.