Juntar repository e collections é possível?  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
Thiago Senna
GUJ Master
[Avatar]

Membro desde: 11/02/2005 08:08:02
Mensagens: 1595
Offline

Olá,

andei pensando (ou viajando?) na possibilidade de juntar repository e collections. Por exemplo:






Gostaria de saber a opinião de vocês. Por exemplo: algo no DDD reprovaria essa idéia? É tecnicamente inviável? A dificuldade vale a pena? Estou agregando valor para o meu domínio?

Enfim, gostaria de saber a opinião do grupo


Até +
[Email]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

Eu não gosto muito da idéia por alguns motivos:

   - você vai ter que implementar todos os métodos de List. Eu diria que nunca você vai precisar disso tudo.
   - você vai ficar tentado a implementar métodos que não façam nada só para obedecer o contrato.
   - Geralmente as operações significativas do seu Repository, exceto adicionar e remover não estão no contrato da interface List.
   - Outras pessoas que usarem esse repositório vão com toda vontade achando que faz tudo que uma List faz e irão se decepcionar.
   - Caso você decida realmente implementar toda a interface (que seria o correto), imagine o trabalhinho para implementar alguns métodos como por exemplo iterator() e seus primos próximos?
   - Quando você quiser usar os métodos que só estarão na implementação, terá que fazer uma chamada não-polimórfica.

Em fim, isso tudo se resume em uma coisa: Respeitar um contrato que para o cenário do Repository não faz muito sentido.

Apesar do conceito do Repository ser algo "como se fosse uma Collection", seu contrato será diferente do da API Collections do Java, pelo menos IMO.

[]s


This message was edited 5 times. Last update was at 06/03/2008 10:46:42


Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
Thiago Senna
GUJ Master
[Avatar]

Membro desde: 11/02/2005 08:08:02
Mensagens: 1595
Offline

emerleite wrote: Em fim, isso tudo se resume em uma coisa: Respeitar um contrato que para o cenário do Repository não faz muito sentido.


também pensei nestas possibilidades que você citou. Então, por enquanto, to pensando na possibilidade de respeitar o contrato feito com a interface. Por exemplo, esse código abaixo, apesar de não ser o ideal, já ajudaria:



A classe concreta por sua vez se encarrega apenas de implementar os métodos abstratos. Pode ser uma alternativa, não pode?
[Email]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

Continua com o mesmo problema pois você terá que sobrescrever todos os métodos. Caso contrário quem usar algum método que você não tenha sobrescrito obterá resultados não desejados.

Não é mais fácil você substituir essa herança por composição?

This message was edited 1 time. Last update was at 06/03/2008 11:03:51


Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
Thiago Senna
GUJ Master
[Avatar]

Membro desde: 11/02/2005 08:08:02
Mensagens: 1595
Offline

emerleite wrote:Não é mais fácil você substituir essa herança por composição?

Sim sim! Por isso no primeiro exemplo usei interface, para dar liberdade pra nossa imaginação . Usei herança neste exemplo por praticidade. Na prática, optaria com composição.

emerleite wrote:Continua com o mesmo problema pois você terá que sobrescrever todos os métodos. Caso contrário quem usar algum método que você não tenha sobrescrito obterá resultados não desejados.

Pode ser, mas e se eu conseguisse uma solução onde eu não precisasse sobrescrever nenhum método da interface Collection/List?

Por exemplo, no caso de uma composição, como você sugeriu, eu sobrescrevo todos os métodos da interface List para delegar para um ArrayList. Ou seja, meu repositório continua sendo na íntegra uma Collection. Mas é aqui onde começam a surgir as dificuldade técnicas, ao meu ver. O hibernate talvez consiga numa boa identificar que foi adicionado um item na collection, já a implementação usando jdbc seria bem mais punk e pode exigir que não nos limitemos em apenas delegar tudo para ArrayList. Ficou claro o meu ponto de vista?
[Email]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

Eu entendi o seu ponto de vista, só não vejo o que estamos ganhando com esse trabalho todo

Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
Thiago Senna
GUJ Master
[Avatar]

Membro desde: 11/02/2005 08:08:02
Mensagens: 1595
Offline

emerleite wrote:Eu entendi o seu ponto de vista, só não vejo o que estamos ganhando com esse trabalho todo

Talvez eu esteja exagerando. Mas o que estou fazendo é questionando o padrão Repository. Se a collection de alunos é um repositório 'natural' de alunos, por que ele não poderia aderir métodos específicos para acessar um centro de armazenamento de dados desacoplado? Ou seja, da forma que é implementado hoje você cria uma collection e um repositório. Essas duas coisas poderiam ser uma coisa só.



ao invés de


tudo bem que turma.addAluno() poderia adicionar aluno na collections e em seguida chamar alunoRepository.add, mas são duas chamadas com a mesma finalidade, não é?

[Email]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

Thiago Senna wrote:Olá,

andei pensando (ou viajando?) na possibilidade de juntar repository e collections.
Gostaria de saber a opinião de vocês. Por exemplo: algo no DDD reprovaria essa idéia? É tecnicamente inviável? A dificuldade vale a pena? Estou agregando valor para o meu domínio?



O padrão repository defini-se como "Acesso ao conjunto de instancias da entidade como se fosse uma coleção"
básicamente significa : "Acesso ao collection de X sem implementar Collection"

A ideia é que existam métodos como add e remove igual aos de Collection, mas que não tenham que existir métodos como toArray(), addAll() , retain(), etc..
Portanto, o proprio padrão está dizendo "Não faça repository implementar Collection".
Por maioria de razão não faz sentido implementar List (os dados não são indexados por posição)
Em resumo: não vale a pena, não está agregando valor é mais dificil de implementar coerentemente e pior: vai contra o propósito do próprio padrão Repository.

This message was edited 1 time. Last update was at 06/03/2008 12:47:36


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
le-silva
Java Ninja
[Avatar]

Membro desde: 31/01/2003 10:21:32
Mensagens: 260
Offline

Também não acho legal não, Thiago. Concordo com o Emerleite.

Sugestão?



E nas interfaces que extenderem esta, você adiciona métodos específicos de listarBlaBlaBla, etc, etc, etc. Ou então, implementa um get ou list com um search criteria da vida nesta própria interface básica, e boa.

Sigo nessa linha... IMHO...

Abraço!

Leandro Silva

{ :blog => 'leandrosilva.com.br' , :twitter => '@codezone' }
[Email] [WWW]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

Thiago Senna wrote:


ao invés de


tudo bem que turma.addAluno() poderia adicionar aluno na collections e em seguida chamar alunoRepository.add, mas são duas chamadas com a mesma finalidade, não é?



Perái.. agora vc viajou. O que tem a haver implementar ou não collection com o adicionar o aluno explicitamente ao seu repositorio ?

O correto sempre será



Se a implementação especifica pode lidar com chamadas implicitas aos outros repositorios é outra historia.

Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

É por isso que Repository é um Design Pattern . Existe um problema reccorente que é o fato dos objetos não serem auto persistidos. A melhor forma que se encontrou pra resolver isso foi essa. Tinhamos o DAO, que na verdade é um DataMapper misturado com Repository IMO. Achou-se interessante criar esse conceito de Repository para fazer parte do domínio.

Esse problema que você disse é justamente porque a collection não é o DB. O fato é que o os objetos não sendo auto-persistidos, o Repository se tornou uma alternativa elegante para termos algo no nosso Domain Model.

Quando a Collection, sinceramente não acho essa implementação vá ajudar. Mesmo que você crie um adapter não acho que vá ganhar muita coisa. Ainda mais se falarmos de sistemas web onde ao final da requisição os objetos morrem e na próxima vai ter que chamar tudo novamente.

No seu caso, vai adicionar o Aluno a turma e dificilmente após essa operação você vai querer uma lista dos alunos daquela turma. Talvez no próximo request você precise mas ai de fato seu objeto Turma já se perdeu. O máximo que você vai ter é o ID da turma armazenado no cliente de alguma forma e vai passar isso ao servidor pra começar tudo denovo.

Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

emerleite wrote:Tinhamos o DAO, que na verdade é um DataMapper misturado com Repository IMO.

Isso só acontece quando insistimos em colocar métodos de negócio dentro do DAO. Mas o DAO não foi feito pra isso.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

tnaires wrote:
emerleite wrote:Tinhamos o DAO, que na verdade é um DataMapper misturado com Repository IMO.

Isso só acontece quando insistimos em colocar métodos de negócio dentro do DAO. Mas o DAO não foi feito pra isso.

AHM????? Pode explicar isso? Quem disse isso?

This message was edited 1 time. Last update was at 06/03/2008 13:10:56


Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
Thiago Senna
GUJ Master
[Avatar]

Membro desde: 11/02/2005 08:08:02
Mensagens: 1595
Offline

sergiotaborda wrote:O padrão repository defini-se como "Acesso ao conjunto de instancias da entidade como se fosse uma coleção" básicamente significa : "Acesso ao collection de X sem implementar Collection"

Então fechado -> O padrão repository não é e nem pode ser uma Collection.

Tentarei continuar a discussão para essa abordagem que coloquei no início do tópico, mas consciente que Collections e Repository são coisas distintas.

sergiotaborda wrote:O correto sempre será

1. turma = new Turma();
2. aluno = new Aluno();
3. turma.addAluno(aluno);
4.
5. turmaRepository.add(turma);


Se a implementação especifica pode lidar com chamadas implicitas aos outros repositorios é outra historia.


À partir desta colocação tentarei colocar minha insatisfação com repository: imagine o seguinte caso:



Se por baixo dos panos é hibernate por exemplo, esse código funciona que uma beleza. Se for JDBC por debaixo dos panos o jeito mais fácil de garantir que aluno será persistido é usar alunoRepository.add(aluno);

Ou seja, você ainda não está completamente desamarrado da tecnologia de persistência. Mas enfim, não sou eu quem vai resolver este problema, hehe. O que acho desperdício é o fato de que em turma.addAluno eu já fiz uma chamada em alunos.add. Qualquer coisa fora disso, ao meu ver, é gambi para alinhar OO e Tabela Relacional.

emerleite wrote:É por isso que Repository é um Design Pattern . Existe um problema reccorente que é o fato dos objetos não serem auto persistidos. A melhor forma que se encontrou pra resolver isso foi essa. Tinhamos o DAO, que na verdade é um DataMapper misturado com Repository IMO. Achou-se interessante criar esse conceito de Repository para fazer parte do domínio.


A Collections no fim são usados no domínio. Uma solução não poderia ser deixar elas um pouco mais espertinhas e torná-las mais específicas para o negócio?

Enfim, o que me parece é que já não estou mais falando de repositório, mas de uma opção a ele. Uma coleção específica para o negócio. (humm... to viajando!)


Só pra somar na discussão comecei a dar uma olhada em como poderia implementar isso no hibernate e achei este artigo: http://www.javalobby.org/java/forums/m91831280.html
[Email]
Fabio Kung
JavaEvangelist

Membro desde: 08/03/2004 08:24:47
Mensagens: 445
Localização: São Paulo
Offline

Oi Thiago,

Eu também não gosto muito da idéia por um outro ponto de vista:
Por que é mesmo que você precisa se referenciar a um Repositório como List?

Para você satisfazer sua tentação, apenas faça como eu. Chame o repositório de Collection sem implementar java.util.Collection, mas não conta para ninguém!

Procurando por oportunidades de emprego?
OndeTrabalhar.com
OndeTrabalhar.com Java?


http://blog.caelum.com.br


Fabio Kung
[WWW] [MSN] [ICQ]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team