Padrão repository

Pessoal, estava lendo sobre o padrão repository e pelo que entendi, este padrão é como se fosse um DAO so que de negócio. Ele recupera informações de uma fonte de dados, so que não caberia a ele a infra necessária para ele. Na verdade ele seria alguem que processa ou distribui os dados que recebeu através de um DAO. Está correto este meu entendimento ?

Por exemplo, trazendo pra minha relalidade atual. Hj estou mexendo em um sitema que é assim : VIEW (Managed Bean) – > uma classe chamada Business que possui as regras de negócios e classes DAOs que recupera as informações do banco.

Caso eu resolvesse usar o repository (Isso é so suposição para meu entendimento, não faz parte do meu trabalho não, nem sou arquiteto), eu teria então VIEW --> BUSINESS–> REPOSITORY --> DAO.

O repositóry não criaria um passo redundante, levando em conta que ja tenho uma camada tratando negócio ? Posso crer que o repository dispensa outras camadas de negócio ? Ou ele seria complemento ao negócio ?

REPOSITORY é a mesma abstração de um DAO. Por isso não faz sentido usar VIEW --> BUSINESS–> REPOSITORY --> DAO.
Então use VIEW --> BUSINESS–> REPOSITORY --> SGDB.
Caso sua filosofia de REPOSITORY sofrer alteração, vc pode alterar polimorficamente.

Acredito que seria algo mais ou menos assim…

Acredito que não ficaria redundante… estive lendo sobre o assunto recentemente e entendi que deveriam existir ambos Repository e DAO, já que o Repository não deveria se envolver em questões de infra estrutura…

No material que estive lendo (estou sem os links aqui, mas um foi no blog do sergio taborda e outro no blog da caelum) me pareceu uma forma de oferecer aos beans de modelo um pouco mais de responsabilidade…

Os Repository’s ficariam no mesmo pacote dos beans e seriam uma espécie de extensão do modelo… Pelo que entendi, esses Repository’s apenas encapsulariam as chamadas aos daos e fariam a tradução das consultas de alto nível (sem uso de sql ou outro comando de infra) para que os daos pudessem executa-las e isolariam ainda mais a camada de infra…

Pelo que pude entender, cada bean de modelo poderia ter uma instancia desse Repository para que pudesse oferecer consultas de forma mais simples dando a ideia de que as classes de negocios trabalham com uma lista de objetos em memória o inves de algo no banco de dados… e os objetos com a regra de negocio iriam trabalhar com eles ao inves de usar os daos diretamente…

não sei se falei besteira… se tiver me corrijam…

A questão é q não envolve…

  1. Faz 1 interface RepositoryCliente com as operações.
  2. Gere filosofias diferentes de respositorios polimorficamente…tipo:
  • RepositoryClienteOracleImp
  • RepositoryClienteMySqlImp
  • RepositoryClienteWebServiceImp
  • RepositoryClienteLDAPImp
  • Etc…
    Não existe necessidade de colocar outra abstração de DAO dentro…é so deixar o polimorfismo fazer o trabalho dele…

A questão é q não envolve…

  1. Faz 1 interface RepositoryCliente com as operações.
  2. Gere filosofias diferentes de respositorios polimorficamente…tipo:
  • RepositoryClienteOracleImp
  • RepositoryClienteMySqlImp
  • RepositoryClienteWebServiceImp
  • RepositoryClienteLDAPImp
  • Etc…
    Não existe necessidade de colocar outra abstração de DAO dentro…é so deixar o polimorfismo fazer o trabalho dele…

[/quote]

Vou insistir para poder entender…

Se a abstração do Repository é a mesma do DAO, qual a diferença em usar um ou outro modelo?

Implementando dessa forma eu não vou estar envolvendo o meu Repository com a infra? Como que o RepositoryClienteMySqlImp, por exemplo, faria uma inserção sem usar dao ou outro mecanismo que trabalhe diretamente com a infra? Ele enviaria um comando sql diretamente (caso estivessemos usando jdbc puro) para o banco?

Acabei encontrando esse diagrama sobre esse “padrão” (hum… nunca usei anexo aqui… espero ter enviado corretamente).

E acabei entendendo que o principal motivo para existência do Repository era a tradução de consultas, para que consultas mais complexas pudessem ser elaboradas de forma “mais simples”.

Fiquei procurando e encontrei os links dos quais falei, seguem:

http://sergiotaborda.wordpress.com/desenvolvimento-de-software/java/patterns/repository/

http://blog.caelum.com.br/repository-seu-modelo-mais-orientado-a-objeto/

http://manifesto.blog.br/1.5/Blog/Programa%C3%A7%C3%A3o/repository-pattern.html

Desculpe se estiver falando bobagem, mas acho que Repository e DAO tem propósitos um pouco diferentes e podem coexistir sem problemas, e, mais do que isso, quero entender para poder aplicá-lo corretamente em alguns testes que pretendo fazer aqui…


Veja o livro do DDD do Eric Vans falando sobre o padrão repositório na pagina 147 e compare com o JEE patters - http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html.
Vc vera q semanticamente falando não existe diferença nenhuma…o Eric Vans apenas trocou o nome para gerar uma “grupo de padrões” voltados para a aplicação sistemática DDD.
Vc vc até pode fazer assim, mas vai duplicar uma abstração desnecessária…adicionando uma camada polimorfica sem sentido arquitetural…
Vc pode tentar me convencer ao contrario…caso vc justifique ter 2 abstrações polimórficas…e ai?
Descreva em que caso vc haverá diferentes implementações de Repositorios e DAO’s…

A forma como eu uso o Repository é a seguinte, exemplo de Cliente:

public interface ClienteRepository {
//todos os métodos aqui
}

public class ClienteDao implements ClienteRepository {
//os métodos sobrescritos aqui
}

O DAO que fará a conexão com o banco, porém nas minhas lógicas vou trabalhar apenas com o Repository.

[quote=j0nny]A forma como eu uso o Repository é a seguinte, exemplo de Cliente:

public interface ClienteRepository {
//todos os métodos aqui
}

public class ClienteDao implements ClienteRepository {
//os métodos sobrescritos aqui
}

O DAO que fará a conexão com o banco, porém nas minhas lógicas vou trabalhar apenas com o Repository.[/quote]
É justamente oq estou falando :smiley:

Justificara então eu usar o respository junto com DAO´s para encapular a implementação da infra propriamente dita, então :
Por exemplo, dentro do meu ClienteRepository haveriam as regras que me levariam ao uma implementação de DAO específica, onde eu poderia tratar e manipular os dados antes da chamada DAO, conforme as necessidades da implementação

  • ClienteRepository encapularia DAOClienteOracleImp, DAOClienteMySqlImp, DAOClienteWebServiceImp ,DAOClienteLDAPImp

Que acham ?

[quote=rogeriosantos77]Justificara então eu usar o respository junto com DAO´s para encapular a implementação da infra propriamente dita, então :
Por exemplo, dentro do meu ClienteRepository haveriam as regras que me levariam ao uma implementação de DAO específica, onde eu poderia tratar e manipular os dados antes da chamada DAO, conforme as necessidades da implementação

  • ClienteRepository encapularia DAOClienteOracleImp, DAOClienteMySqlImp, DAOClienteWebServiceImp ,DAOClienteLDAPImp

Que acham ?
[/quote]

Exatamente isso, mas tratar os dados não são responsabilidade nem do Repository nem do Dao, e sim do seu objeto de domíbio, no caso, Cliente.

Pelo pouco que conheço, algumas das diferenças seriam as seguintes:

  1. O estilo da interface é diferente, o repository tem uma carinha de Coleção.
    Mais ou menos assim:
userDao.save(User usr);
userDao.findById(int userId);
userDao.deleteUser(int userId);
// Esta interface transmite uma característica de "utilitário para acesso ao BD".


userRepository.add(User usr);
userRepository.get(int userId);
userRepository.remove(User usr);
// Já essa outra simula o próprio mecanismo de persistência. Para o restante da aplicação,
// é como se o banco de dados fosse um simples objeto, uma lista em memória.
  1. O Repository é parte do domínio de negócio, portanto pode ser acessado a partir de um Controller por exemplo. Elimina a necessidade daqueles business objects que não fazem nada além de delegar para o Dao.

Agora, sobre o foco principal… para mim não está claro se o Repository precisaria de um Dao para abstrair a camada de persistência real.

[quote=gomesrod]Pelo pouco que conheço, algumas das diferenças seriam as seguintes:

  1. O estilo da interface é diferente, o repository tem uma carinha de Coleção.
    Mais ou menos assim:
userDao.save(User usr);
userDao.findById(int userId);
userDao.deleteUser(int userId);
// Esta interface transmite uma característica de "utilitário para acesso ao BD".


userRepository.add(User usr);
userRepository.get(int userId);
userRepository.remove(User usr);
// Já essa outra simula o próprio mecanismo de persistência. Para o restante da aplicação,
// é como se o banco de dados fosse um simples objeto, uma lista em memória.
  1. O Repository é parte do domínio de negócio, portanto pode ser acessado a partir de um Controller por exemplo. Elimina a necessidade daqueles business objects que não fazem nada além de delegar para o Dao.

Agora, sobre o foco principal… para mim não está claro se o Repository precisaria de um Dao para abstrair a camada de persistência real.[/quote]

Exatamente isso, o Repository serve pra vc abstrair a forma como vc está armazenando seus objetos, e o Repository faz parto do modelo de negócio.
O DAO fica com a parte ‘suja’ da coisa toda.

Poderia ter um Cliente Repository que seria usado nas minhas regras de negócio, sem me importar se por baixo dele vou ter um ClienteTxtDao, ClienteOracleDao, ClienteMemoriaDao ou qualquer outra coisa.

Veja o livro do DDD do Eric Vans falando sobre o padrão repositório na pagina 147 e compare com o JEE patters - http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html.
Vc vera q semanticamente falando não existe diferença nenhuma…o Eric Vans apenas trocou o nome para gerar uma “grupo de padrões” voltados para a aplicação sistemática DDD.
Vc vc até pode fazer assim, mas vai duplicar uma abstração desnecessária…adicionando uma camada polimorfica sem sentido arquitetural…
Vc pode tentar me convencer ao contrario…caso vc justifique ter 2 abstrações polimórficas…e ai?
Descreva em que caso vc haverá diferentes implementações de Repositorios e DAO’s…
[/quote]

Hum… acho que entendi…

No que andei lendo o Repository existe como um objeto além do DAO apenas para poder existir dentro do “pacote do domínio” e atender ao DDD… ao delegar as tarefas para o dao… ele não passa de um dao mascarado que pode existir num pacote separado dos daos propriamente dito… vendo assim, consigo entender e concluir que são a mesma coisa…

hum… não sei dizer quando são necessárias duas implementações distintas (DAO e Repository) nem se são realmente necessárias… vou continuar estudando…

valew

[quote=rogeriosantos77]Justificara então eu usar o respository junto com DAO´s para encapular a implementação da infra propriamente dita, então :
Por exemplo, dentro do meu ClienteRepository haveriam as regras que me levariam ao uma implementação de DAO específica, onde eu poderia tratar e manipular os dados antes da chamada DAO, conforme as necessidades da implementação

  • ClienteRepository encapularia DAOClienteOracleImp, DAOClienteMySqlImp, DAOClienteWebServiceImp ,DAOClienteLDAPImp

Que acham ?
[/quote]
Como ja falei…acho uma opção ruim…quando e para que vc implementaria variantes do seu ClienteRepositoryImp1, ClienteRepositoryImp2?
Veja que a resposta fica q vc vai duplicar o ClienteRepository quando variar o Dao…duplicadamente sem justificativa arquitetural.

[quote]Hum… acho que entendi…

No que andei lendo o Repository existe como um objeto além do DAO apenas para poder existir dentro do “pacote do domínio” e atender ao DDD… ao delegar as tarefas para o dao… ele não passa de um dao mascarado que pode existir num pacote separado dos daos propriamente dito… vendo assim, consigo entender e concluir que são a mesma coisa…

hum… não sei dizer quando são necessárias duas implementações distintas (DAO e Repository) nem se são realmente necessárias… vou continuar estudando…

valew[/quote]

Que bom q vc visualizou a situação arquitetural!! bem vindo ao time dos PROJETISTAS kkkkk.
Meu objetivo é levar vc a visualizar a arquitetura e tomar suas próprias decisões.
T+

Pessoal, só uma duvida de tudo isso.

Dao entra em infra instrutura, ok, pode até ter query SQL tranquilo nessa camada.
Repository não, mexe com dados, mas nao chega a ser ‘baixo nivel’, infraestrutura.

Minha dúvida é, do mesmo modo que eu não posso (é lei!) acessar diretamente o Dao em uma View/Controller layer, eu não poderia acessar o Repository?

Porque não sei se é a intenção, mas ai eu usaria Dao e Repository, e não precisaria colocar na camada de negocios, logica referente a acesso a dados, faria isso só no repository (os get users, save user) e acessaria direto na layer View, e na camada de negocios ficaria só os valida user, etc…