| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 12/02/2010 20:29:42
|
garcia-jj
JWizard
Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline
|
Em todas as minhas aplicações tento abstrair os repositórios com interface + implementação. Por exemplo, tenho uma interface UserRepository e uma implementação JpaUserRepository. Assim uso na minha camada de negócio apenas a UserRepository.
Dessa forma eu posso futuramente matar a classe JpaUserRepository e usar uma LdapUserRepository e a camada de negócio nada muda. Além do mais usando essa idéia eu somente pelo nome já sei se tal classe usa JPA, LDAP ou qualquer outra coisa...
O que vocês tem usado para os repositórios? Há realmente um ganho quando a essa abstração ou estou fazendo algo desnecessário? Obviamente sempre me pareceu uma boa idéia, porém meu projeto cresceu tanto que penso se vale a pena escrever o dobro de classes para os repositórios.
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/02/2010 13:03:38
|
mateusbrum
JavaBaby
![[Avatar]](/images/avatar/be6ea238d9be0fc60080a6f8a8188817.png)
Membro desde: 21/01/2007 22:55:29
Mensagens: 84
Offline
|
Você vai utilizar essa separação de implementação que descreveu acima ?
É muito custosa a separação?
É muito complexa?
Se não ?
Para que fazer isso ?
|
Mateus Henrique Brum
Analista Programador Java
Sun Certified Java Programmer 6.0
Sun Certified Web Component Developer 5.0 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 09:29:24
|
garcia-jj
JWizard
Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline
|
mateusbrum, não entendi muito bem suas perguntas.
De qualquer forma estou usando isso atualmente em um sistema meu. Complexo não é não, porém como o sistema cresceu muito, achei que eu poderia encurtar um pouco o assunto. Porém eu não queria perder o desacoplamento entre ambas camadas. E minha indagação é se realmente é válido eu não possuir acoplamento entre elas.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 10:13:35
|
renzonuccitelli
GUJ Master
Membro desde: 17/09/2008 12:58:32
Mensagens: 1133
Offline
|
Essa implementação lembra muito a arquitetura proposta para a camada DAO no Hibernate in Action. Em particular acho bem interessante, pq usa bem o conceito de programar voltado a interface, e isso é muito bom para manutenção, teste unitário e etc. O Guerra, editor da Munda Java, me falou a algum tempo, qdo me orientou no TCC, que quando vc começa a usar interfaces é quando realmente vc está programando em OO, já que está conseguindo abstrair as coisas. Em particular, eu concordo com ele
|
Renzo Nuccitelli
Engenheiro de Computação - ITA
http://nuccitec.com.br/
http://blog.nuccitec.com.br/
http://jcoltrane.sf.net
http://jfera.nuccitec.com.br/
http://code.google.com/p/webapp-ce/
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 13:51:58
|
mateusbrum
JavaBaby
![[Avatar]](/images/avatar/be6ea238d9be0fc60080a6f8a8188817.png)
Membro desde: 21/01/2007 22:55:29
Mensagens: 84
Offline
|
A utilidade obvia que vejo para isso é nos testes, para com a idéia de que "posso precisar mais tarde" é furada.
Em particular acho bem interessante, pq usa bem o conceito de programar voltado a interface, e isso é muito bom para manutenção, teste unitário e etc.
Quando ele disse isso, ele quis dizer "voltado ao contrato (abstração)", isso não quer dizer que tu tem que meter interface em tudo que vê.
Lembre-se que não é apenas a interface que garante um contrato.
|
Mateus Henrique Brum
Analista Programador Java
Sun Certified Java Programmer 6.0
Sun Certified Web Component Developer 5.0 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 17:16:47
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
garcia-jj wrote:Em todas as minhas aplicações tento abstrair os repositórios com interface + implementação. Por exemplo, tenho uma interface UserRepository e uma implementação JpaUserRepository. Assim uso na minha camada de negócio apenas a UserRepository.
Dessa forma eu posso futuramente matar a classe JpaUserRepository e usar uma LdapUserRepository e a camada de negócio nada muda. Além do mais usando essa idéia eu somente pelo nome já sei se tal classe usa JPA, LDAP ou qualquer outra coisa...
O que vocês tem usado para os repositórios? Há realmente um ganho quando a essa abstração ou estou fazendo algo desnecessário? Obviamente sempre me pareceu uma boa idéia, porém meu projeto cresceu tanto que penso se vale a pena escrever o dobro de classes para os repositórios.
A sua ideia está correta em essência, mas tecnicamente isso ai não são repositorios.
A diferença é que o repositorio depende apenas do dominio. Então o seu UserRepository é um repositorio mesmo. O nome do repositorio é construido como [NomeDaEntidade]Repository. O JpaUserRepository e o LdapUserRepository são estratégias para o repositorio. eles poderiam-se chamar JpaStrategyUserRepository. A diferença é que o nome deles é montado com o nome da tecnologia. Ou seja, algo que não é do dominio.
Se vc faz JpaUserRepository herdar/implementar UserRepository vc não está usando o padrão Repositorio como deve ser. Vc está usando Strategy na realidade ("uma interface várias estratégias de acesso"). Vc precisa que a estratégia seja plugável no repositorio. Desta forma vc usa sempre o mesmo objeto, e pode mudar a estratégia depois, sem usar herança. Ou seja, vc sempre injeta UserRepository onde precisar, e injeta a estratégia de acesso no repositorio ao inves de injetar a estratégia diretamente onde é usada.
É por isso que sempre digo que repositorios não são interfaces.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 19:27:06
|
Bruno Laturner
GUJ Expert
![[Avatar]](/images/avatar/5800ccd9514fd789d08e5831951aa6bc.jpg)
Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline
|
Programar para interfaces(o conjunto de métodos públicos de uma classe) não é a mesma coisa que criar um interface(a palavra reservada) em Java e sair criando Xpto e XptoImpl (Ou IXpto e AlgumaCoisaXpto) pelo sistema todo.
Programar para interfaces significa você ler a documentação do método, e se basear somente nisto para desenvolver os seus programas. O que tem dentro do corpo dos métodos deve ser apagado da tua mente.
Sobre abstrair ou não o repositório, eu digo que isto é indispensável para testes, e na prática só para testes. Digo no sentido que ninguém é maluco de trocar o Oracle por outro banco relacional. Não quer dizer que você deve praticar um vendor lock-in ativamente, boas práticas de programação sempre valerão acima de tudo, mas deixe este problema para a hora em que se tornar um problema, no melhor estilo YAGNI.
|
A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/02/2010 23:00:05
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
Bruno Laturner wrote:
Sobre abstrair ou não o repositório, eu digo que isto é indispensável para testes, e na prática só para testes. Digo no sentido que ninguém é maluco de trocar o Oracle por outro banco relacional. Não quer dizer que você deve praticar um vendor lock-in ativamente, boas práticas de programação sempre valerão acima de tudo, mas deixe este problema para a hora em que se tornar um problema, no melhor estilo YAGNI.
O problema de seguir este conselho é que é caro. Quando vc implanta um sistema e descobre que o Oracle que estava nos requisitos é o 7 e não o 10 como vc pensou, ou pior, quando lhe disseram que era Oracle, mas esqueceram de lhe dizer que mudaram param para MYSQL entretanto.
Sempre, sempre uma boa arquitetura é aquela que está preparada para mudar. Isto não significa que vamos implementar todos os XPTOImmpl que nos lembremos, mas sim que vamos deixar o sistema desacoplado. Desacoplar passar por diferentes coisas e desenhar para interfaces é apenas uma delas.
Um artigo muito bom na JavaMagazine deste mes do Osvaldo Doederlein reflete exactamente isto.
Saber abstrair é necessário para saber desacoplar. E saber desacoplar é necessário para você não passar horas refactorando um código que vc não mais lembra o que faz.
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/04/2010 13:27:34
|
garcia-jj
JWizard
Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline
|
sergiotaborda wrote:Se vc faz JpaUserRepository herdar/implementar UserRepository vc não está usando o padrão Repositorio como deve ser. Vc está usando Strategy na realidade ("uma interface várias estratégias de acesso"). Vc precisa que a estratégia seja plugável no repositorio. Desta forma vc usa sempre o mesmo objeto, e pode mudar a estratégia depois, sem usar herança. Ou seja, vc sempre injeta UserRepository onde precisar, e injeta a estratégia de acesso no repositorio ao inves de injetar a estratégia diretamente onde é usada.
É por isso que sempre digo que repositorios não são interfaces.
Sérgio, entendi bem a tua idéia. Nesse caso fiz mesmo um merge entre repository e strategy. Vou rever isso.
Bruno Laturner wrote:Sobre abstrair ou não o repositório, eu digo que isto é indispensável para testes, e na prática só para testes. Digo no sentido que ninguém é maluco de trocar o Oracle por outro banco relacional. Não quer dizer que você deve praticar um vendor lock-in ativamente, boas práticas de programação sempre valerão acima de tudo, mas deixe este problema para a hora em que se tornar um problema, no melhor estilo YAGNI.
Bruno, na verdade essa coisa de trocar de banco é uma "lenda urbana" mesmo, concordo com você. É tão pouco provável que você troque de banco de dados que nem vale a pena fazer isso. Porém a minha intenção é de esconder para as camadas de serviço quem é meu repositório. Posso ter um JPA ou até mesmo acesso ao filesystem sem que as classes de serviço sintam a diferença, ou seja, qualquer que seja o repositório ele irá respeitar a sua interface (mesmo que seja 1 interface para 1 implementação).
sergiotaborda wrote:Sempre, sempre uma boa arquitetura é aquela que está preparada para mudar. Isto não significa que vamos implementar todos os XPTOImmpl que nos lembremos, mas sim que vamos deixar o sistema desacoplado. Desacoplar passar por diferentes coisas e desenhar para interfaces é apenas uma delas.
Totalmente de acordo.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/04/2010 17:54:59
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
.
This message was edited 1 time. Last update was at 01/04/2010 17:55:20
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/04/2010 18:01:38
|
mochuara
GUJ Master
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline
|
garcia-jj wrote:mateusbrum, não entendi muito bem suas perguntas.
De qualquer forma estou usando isso atualmente em um sistema meu. Complexo não é não, porém como o sistema cresceu muito, achei que eu poderia encurtar um pouco o assunto. Porém eu não queria perder o desacoplamento entre ambas camadas. E minha indagação é se realmente é válido eu não possuir acoplamento entre elas.
Se vc não quer perder o tal desacoplamento, sua pergunta foi respondida por vc mesmo. Eu particularmente prefiro 1000x código reduzido do que código abstraído/desacoplado só por algum prazer em abstrair/desacoplar.
This message was edited 1 time. Last update was at 01/04/2010 18:02:41
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2010 11:44:35
|
garcia-jj
JWizard
Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline
|
Ressuscitando o tópico, essa semana saiu no blog da Caelum um artigo sobre repositórios. http://blog.caelum.com.br/2010/07/26/possibilidades-de-design-no-uso-do-seu-generic-dao/
Nesse artigo os repositórios possuem interface e implementação, unidos as DAOs.
|
http://github.com/garcia-jj
Não respondo dúvidas via MP. Use o fórum. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/07/2010 20:25:06
|
luizSC
JavaBaby
Membro desde: 29/07/2010 19:10:45
Mensagens: 76
Offline
|
Garcia,
Utilizo uma única camada na implementação do repositório, que por sua vez, usa um DAO. Esse DAO possui uma implementação diferente para cada tecnologia de persistência. Há um sistema que roda em dispositivos móveis que quando fica off-line, precisa persistir utilizando o sistema de arquivos do dispositivo. Troca-se o DAO e a vida segue.
This message was edited 1 time. Last update was at 29/07/2010 20:33:15
|
|
|
 |
|
|