Repository: seu modelo mais Orientado a Objeto
Por Fabio Kung em 09/06/07Já tem algum tempo que a excelente discussão no GUJ estava me motivando a escrever a respeito.
Para ambientar, a principal discussão é usar:
Fornecedor fornecedor = ...;
List
Ou:
Fornecedor fornecedor = ...;
List
Já que posts na forma de diálogos costumam ser muito interessantes, aproveito um papo que eu e o Paulo Silveira tivemos.
Paulo: credo, achei horroroso isso da classe de domínio acessar o repositório
Paulo: mas fica bonitinha a sentença
Fabio: horroroso pq? vc prefere procedural?
Fabio: repositório é domínio tb
Fabio: um List, um Map são repositórios
Fabio: vc acha acessar List e Map horroroso?
Paulo: tem certa razão
Paulo: mas entao poderia chamar o DAO diretamente de repositório
Fabio: em muitos casos poderíamos
Fabio: eu só estava pensando num jeito legal de injetar
Paulo: desde que o cara não receba os objetos de dominio
Fabio: talvez com interceptor de session, ou listener
Fabio: ou então injeta nos métodos load()
Paulo: então. Complicado um Usuario sempre precisar de Repositorio!
Fabio: todo usuário não
Fabio: só Usuário Managed
Fabio: quando vc dá new num Usuário, vc tb não consegue navegar em relacionamentos
Fabio: só faz sentido pegar relacionamento em managed
Paulo: certo
Paulo: mas olha só
Paulo: vai ter Usuario com repositório e outro sem
Paulo: em alguns vc vai poder chamar o método que faz buscas, em outros não
Fabio: mas isso já é assim
Paulo: não com o dao
Fabio: imagina Usuario @OneToMany Categoria
Paulo: certo
Fabio: vc só consegue chamar usuario.getCategorias() no managed, mesma coisa
Fabio: só vai poder chamar usuario.getCategoriasEspeciais() no managed
Fabio: não adianta dar new Usuario().getCategoriasEspecias();
Paulo: hum… entendi! Podia ser um interceptor como fizemos no caelumweb
Paulo: aí ele setava um atributo privado
Fabio: Ou então o próprio load do dao/repository pode fazer isso.
Paulo: mas sei la, baita arquiteturazinha complicada
Fabio: nada! só injetar o repositório
Fabio: o resto é simples
Fabio: em vez de chamar no dao, que é procedural, chama via getter
Paulo: não não, você tem razão. É facílimo de implementar
Paulo: mas tipo, é muita coisa
Fabio: muita coisa do jeito que estão falando no tópico do GUJ! 500 camadas…
Fabio: Repository não precisa nem ser interface
Paulo: aquele interceptador que fizemos para gravar no lucene já não gosto muuuuito
Fabio: Repository pode ter referência para Session
Fabio: e não precisa injetar o repositorio na entidade com listener/interceptor
Fabio: poderia ser:
|
Fabio: ou seja, na hora que você recupera uma Entidade managed, ela já vem com o repositório embutido…
Paulo: dessa maneira dá um pouco mais de responsabilidade para os beanzinhos entidades né? fica legal
Fabio: isso!
Paulo: proximo projeto vamos tentar essa abordagem?
Fabio: demorou… ![]()
Fabio: hoje em dia, se vc quiser mostrar um objeto e alguma pesquisa personalizada, vc tem que consultar o objeto e a lista nas lógicas
Fabio: separados! E aí ejetar os dois
Fabio: muito feio
Fabio: geralmente faz-se isso (código usando algum controlador ruinzinho):
|
Fabio: MUITO procedural!
Paulo: cara se aplicarmos essas idéias, com velocity isso ia ficar ANIMAL
Paulo: Ia dar para chamar os métodos a la DAO direto no beanzinho
Fabio: ISSO!
Paulo: #foreach contas in contas.desde(1994)
Fabio: é meu, legal né?
Fabio: com JSP EL dá tb
Paulo: mais ou menos, teriamos de mexer nos evaluators
Fabio: não, soh usar padrão javabean
Fabio: ahhh vc quer passar parâmetro, aí EL não rola mesmo
Fabio: mas é puro DDD, já fiquei pensando bastante sobre o assunto
Fabio: ultimamente que tenho enxergado um jeito legal de aplicar
Paulo: bacana
Paulo: acho q vale a gente testar
Paulo: parava de ficar enfiando getters para expor as coisas para view.
Paulo: FABIO TODO: blogar sobre isso
Feito!
[...] posts em forma de diálogos estão se tornando moda (1 e 2) e como eu não tenho tido muito tempo para escrever decentemente sobre coisas que eu gosto, então [...]
Pingback by IDLs para REST » Nullability » Some crappy scraps on software development — June 10, 2007 @ 7:48 pm
Fabio, excelente este post.
Como ficaria sua classe Fornecedor seguindo este seu modelo?
Obrigado.
Comment by xebe — June 13, 2007 @ 3:41 pm
é, gostaria de saber tbm
como ficaria Fornecedor ??
Comment by Daniel Souza — June 14, 2007 @ 2:59 pm
Recomendo que vocês leiam o tópico do guj (link no começo deste post) na integra. Tem várias alternativas de como ficaria o Fornecedor. Uma alternativa poderia ser:
getContasDesde(Date date) {
public class Fornecedor {
private final FornecedorRepository repo;
public Fornecedor(FornecedorRepository repo) {
this.repo = repo;
}
public List
return repo.getContas(this, date);
}
}
Eu sei que é simplista demais. Esse é apenas um dos jeitos.
Comment by Fabio Kung — June 15, 2007 @ 12:58 pm
E se eu quisesse obter uma lista de todos os Fornecedores do sistema??
esse metodo ficaria dentro da classe Fornecedor?? tipo:
public class Fornecedor {
private final FornecedorRepository repo;
public Fornecedor(FornecedorRepository repo) {
this.repo = repo;
}
public List getTodosFornecedores() {
return repo.getTodosFornecedores();
}
}
vc não acha melhor que essa funcionalidade não exista na classe Fornecedor e seja acessada chamando diretamente do repositorio (que faz parte do dominio)? por exemplo:
fornecedorRepository.getTodosFornecedores();
ao inves de
fornecedor.getTodosFornecedores();
a final de contas estamos querendo saber uma informação especifica de todos os fornecedores, e não daquele especifico!!!
VAleu,
e parabéns pelo post
Comment by Felipe Regalgo — June 21, 2007 @ 9:32 pm
Felipe, ai voce usa o dao mesmo. Esse esquema é para deixar o objeto mais poderoso e com mais responsabilidade, mas nao faz sentido colocar nele um método de instância com cheiro de estático….
Comment by Paulo Silveira — June 21, 2007 @ 10:29 pm
Boa Felipe,
Essa é a velha discussão sobre ActiveRecord x DataMapper, mas nesse caso (e em Java) eu faria repository.getTodosFornecedores().
Comment by Fabio Kung — June 21, 2007 @ 10:40 pm
Eu gostei e nao gostei.
So vale se for para o mesmo objeto(instância, this!) se for pra trazer coisas do tipo, fornecedor.getContasPagar() trazer de uma outra instância porque voce permitiu no conta a pagar pegar o getId, e liberou o acesso do setId ao inves de ser pelo construtor.
Juro que vomitaria!
Comment by Alexandre F. da Silva [afsrj] — July 21, 2007 @ 8:05 am
[...] about Repositories. I’m from Brazil and we have discussed it many times here (see at GUJ and at my post in the Caelum Blog - unfortunately - in pt-BR; perhaps, translation tools can help). I have a personal and pragmatic [...]
Pingback by Comments to Gavin King about DDD and Repositories | Fabio Kung — November 12, 2007 @ 4:29 pm
[...] Perceba que esta classe implementa uma interface, está interface implementa o pattern Repository, este padrão já causou muita polêmica em forums Java como o GUJ por exemplo, recomendo a leitura deste post para entender o padrão: http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/ [...]
Pingback by Integrando Adobe Flex + BlazeDS + SpringFramework + Hibernate - Uma Solução OpenSource para Sistemas Web. (Parte 2 - Final) - Rodrigo Fraga - RIA Evangelist — January 28, 2008 @ 12:00 am
[...] http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/ [...]
Pingback by Apollo-Ti Blog - Aborda tecnologias novas para desenvolvimento de softwares — January 29, 2008 @ 9:50 pm
Boa sorte Juliano! vai em frente! vc é um cara de futuro ainda! hehehehe
Comment by Leila — January 30, 2008 @ 2:59 pm
Eae Fabin!!
parabéns pelo post cara!! Excelente! Ultimamente estive lendo o livro DDD do Eric Evans… e esse seu tópico veio a complementar muita coisa… talvez não tenha resolvido meus problemas, mas provavelmente tenha me trazido mais dúvida rsrsrs! (e isso é muito bom!)
Estou implementando um projeto lá no LSI dessa forma que você sugeriu.. ou pelo menos uma tentativa do repositório injetado automaticamente ao entrar no estado “managed”.
mais uma vez, parabéns!! você ta cada vez mais prodígio!! rsrsr
abraços
Comment by Emerson Moretto — February 12, 2008 @ 5:06 am
[...] Perceba que esta classe implementa uma interface, está interface implementa o pattern Repository, este padrão já causou muita polêmica em forums Java como o GUJ por exemplo, recomendo a leitura deste post para entender o padrão: http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/ [...]
Pingback by Integrando Adobe Flex + BlazeDS + SpringFramework + Hibernate - Uma Solução OpenSource para Sistemas Web. — July 16, 2008 @ 11:03 pm
Eu até agora não sei o que é exatamente um Repositório.
Seria uma espécie de ligação entre o DAO na camada de persistência e o domínio?? E não tenho a menor idéia de para que ele serve!
Comment by Dirceu — September 16, 2008 @ 5:27 am