DAO's nas classes de negócio  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
Rodrigo Carvalho Auler
Virtual Machine Man

Membro desde: 14/02/2003 15:59:17
Mensagens: 564
Localização: Rio de Janeiro
Offline

duardor wrote:E que meu metodo businessMethod precise de uma referência do repositorio para realizar a logica usando tb os atributos preenchidos anteriormente. A pergunta é: como o objeto que implementa o repositório pode ser injetado/atribuido visto que a classe DomainObject não é uma classe gerenciada.
Já pensei em três maneiras:
- AOP: no new eu faria essas injeções. Não sei me parece um overkill... Acho que alguém me disse que o Rod Johnson faz assim... BTW, não gosto muito pois o código não fica muito evidente... mas é uma alternativa
- usar uma Factory ao invés de fazer o new, onde terei oportunidade de injetar os repositórios. Muito manual, um objeto "artificial" à mais, eu sei... Mas é a alternativa que mais me atrai...
- recuperar o repositorio antes e atribui-lo como mais um atributo da minha classe (ARGH!).

Nos meus repositórios eu tenho um método create que já recebe os dados mínimos que o objeto precisa pra ter um estado válido e já injeta as dependências, ou seja, é proibido dar new nos objetos do domain, como uma factory mesmo. E pros objetos vindo do banco pelo hibernate eu uso um interceptor do hibernate que usa o Spring pra injetar as dependências byName.

[]'s

Rodrigo Auler
Fabio Kung
JavaEvangelist

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

duardor wrote:A pergunta é: como o objeto que implementa o repositório pode ser injetado/atribuido visto que a classe DomainObject não é uma classe gerenciada.

Ótima questão! Estava pensando comigo mesmo se mais ninguém se perguntava sobre isso...

Eu ia responder aqui, mas achei melhor blogar a respeito: http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/.

(tá, tá... eu também sou contra ficar linkando para blog no fórum. Mas nesse caso não teve como!)

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


http://blog.caelum.com.br


Fabio Kung
[WWW] [MSN] [ICQ]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

Ok, eu me exedi e peço desculpas.

Kenobi wrote:Já vi vários tópicos seus, com grande auxílio, mas falta o tal do exemplo tangível e acredito que para muitos, a referência acaba ficando confusa e seu empenho foi em vão.


Frequentemente trabalhamos exemplos com pessoas aqui quando elas estão com dificuldades em aplicar conceitos, mas quando eles estão com dificuldades em entender conceitos geralmente é melhor ler sobre o tal conceito antes de perguntar. Como falei antes um exemplo não vai mostrar o que o conceito representa, do contrário não haveriam livros com seus capítulos cheios de exemplos e textos.

Tudo que foi pedido consta na bibliografia -e boa parte disponível online gratuitamente- mas a impressão que tenho é que se acha que é eficaz inferir informação baseado em meia dúzia de postagens num fórum sem conhecer a base da discussão e sem nem querer conhecer.

Existe uma tendência em todas as áreas de se esconder atrás de 'pragmatismo' para não ler e pesquisar mas ainda assim dar opiniões sobre as coisas que não conhecem.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

microfilo wrote:
Eu digo que dá na mesma pois você mesmo disse que a unica diferença entre uma interface UserDAO e UserRepository é o nome!


Eu disse isso? Onde?

microfilo wrote:
Por isso da na mesma, das duas maneiras eu abstraio o código de persistência da minha lógica de negócios. Só o nome da interface vai ser diferente.

Não tem nada haver com a ACtion chamar o DAO ou nem mesmo ter o DAO, pois nisso há o grave problema de uma clara violação de camadas.


Não, o que eu venho falando aqui há alguns posts é que objetos de negócio lidam com Repository, não com DAO. O DAO pdoe ser a real implementação do Repository -ou não- mas apra o objeto de negócios é um Repository, não um DAO que ele nem sabe do que se trata.

Da mesma maneira, se um método receber java.util.List Para ele é uma lista. Se for na verdade um trabolho mega-complexo que guarda os elementos em bases de dados distribuídas não improta, é uma lista. Um Repository não rpecisa ser uma interface, o ponto aqui é a abstração entre List-->ListamegaDistribuida e Repository->DAO.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

duardor wrote:
E que meu metodo businessMethod precise de uma referência do repositorio para realizar a logica usando tb os atributos preenchidos anteriormente. A pergunta é: como o objeto que implementa o repositório pode ser injetado/atribuido visto que a classe DomainObject não é uma classe gerenciada.


Acho que conseguimos simplificar este problema apra: como fazer quando um objeto requer outro para funcionar, não?

Bom, temos 2 questões aí. Primeiro, a relação entre os objetos (Usuario-->RepositoryDao) pode ser parte da invariante do objeto Usuario. Neste caso quando o objeto for criado ele deve ser populado. Factory é normalmente a melhor alternativa para criar objetos complexos, Factories genéricas como o Spring podem ajudar (mas eu abstrairia seu uso).

Na segunda possibilidade temos a relação como pré-condição para a invocação do método. Ou seja: a relação não rpecisa existir, exceto ao se invocar o método que faz uso desta. Neste caso você poderia fazer um itnerceptor para popular a relação on-demand.

Tenho a impressão que esta última abordagem é overkill para a maioria dos problemas. Se você tem objetos com relações delicadas crie-o através de Factories.

Se ter uma Factory é um estorvo muito grande use um FactoryMethod. Poderia ser um método estático na classe, Ruby-like, mas cuidado para não criar elefantes brancos.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
Fabio Kung
JavaEvangelist

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

Se tivesse um ranking com as melhores discussões do GUJ, eu votaria nesta!

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


http://blog.caelum.com.br


Fabio Kung
[WWW] [MSN] [ICQ]
duardor
Virtual Machine Man
[Avatar]

Membro desde: 04/12/2002 16:26:48
Mensagens: 551
Offline

Primeiro, obrigado pelas respostas, este topico realmente têm me ajudado muito e me tendencionado a adotar DDD...
Fabio, muito instrutivo o seu post no teu blog.
pcalcado wrote:
Se ter uma Factory é um estorvo muito grande use um FactoryMethod. Poderia ser um método estático na classe, Ruby-like, mas cuidado para não criar elefantes brancos.

Gostei da idéia mais do que da própria Factory. Algo como Domain.create() ou Domain.getNew()...
Mas pcalcado, um método estático tiraria o repository de onde? Falando um pouco mais de implementação, por ex. usando Spring... O repository sendo um objeto "gerenciado" pelo Spring... Dá até pra fazer uns pequenos "arranjos" (entenda coisas não muito bonitas e não convencionais) para guardar em um atributo estático uma referência ao ApplicationContext e assim ter acesso aos objetos gerenciados pelo Spring... Deste modo o método estático teria acesso a esta referência e conseguiria "injetar" o repository em seu objeto... Mas como já disse não ia ficar muito bonito não... Incluiria fazer as classes do dominio implementar aquela ApplicationContextAware (ARGH!) do Spring...
Como você está implementando isso hoje em seus sistemas? Recomenda algo?

PS: Como o aviso por email tá fazendo falta!!!!

Eduardo Rodrigues
Belo Horizonte - MG
[Email] [MSN] [ICQ]
Rodrigo Carvalho Auler
Virtual Machine Man

Membro desde: 14/02/2003 15:59:17
Mensagens: 564
Localização: Rio de Janeiro
Offline

Do post do Fabio Kung:

O problema de injetar as dependências assim é quando se faz buscas. Se você faz uma busca que retorna 50 objetos como injetar essas dependências? Por isso que uso interceptor do Hibernate.

pcalcado wrote:
Poderia ser um método estático na classe, Ruby-like, mas cuidado para não criar elefantes brancos.

duardor wrote:
Gostei da idéia mais do que da própria Factory. Algo como Domain.create() ou Domain.getNew()...

Não gosto de métodos estáticos. São ruins de testar. Faço os repositórios gerenciados pelo Spring e o create fica no repositório. Tenho tudo a mão pra criar meus objetos.

[]'s

Rodrigo Auler
TriTonE
What is classpath?

Membro desde: 29/07/2005 17:44:07
Mensagens: 6
Localização: Ourinhos - SP
Offline

Segundo alguns textos que li sobre DDD, os factories servem tanto para CRIAR objetos complexos quanto para RECONSTITUIR objetos (por exemplo, objetos carregados do repositório).

Então, seu repositório faz a query utilizando seja lá o que for (jpa, hibernate etc). Seu repositório também terá uma referência a um factory (relativo ao aggregate em questão) e o utilizará para recompor esses objetos antes de repassá-los para a aplicação.
[WWW] [MSN]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

duardor wrote:
Mas pcalcado, um método estático tiraria o repository de onde? Falando um pouco mais de implementação, por ex. usando Spring... O repository sendo um objeto "gerenciado" pelo Spring... Dá até pra fazer uns pequenos "arranjos" (entenda coisas não muito bonitas e não convencionais) para guardar em um atributo estático uma referência ao ApplicationContext e assim ter acesso aos objetos gerenciados pelo Spring... Deste modo o método estático teria acesso a esta referência e conseguiria "injetar" o repository em seu objeto... Mas como já disse não ia ficar muito bonito não... Incluiria fazer as classes do dominio implementar aquela ApplicationContextAware (ARGH!) do Spring...


Não não, o estático foi ilustrativo. Use métodos de instãncia com objetos gerenciados pelo Spring mesmo. Eu costumo fazer exatamente assim. Dificilmente existe um Entity (falando no jargão DDD) que seja criado manualmente, geralmente ele é criado por um Factory Method em um Service (outra vez DDD) que já cuida destas coisas.


--
Um Factory lida com lógica de inicialização complexa. O papel de uma Factory numa paltaforma como Java é agrantir que a invariante do objeto seja cumprida.

Como fatalmente o Repository (ou mesmo um Context Mapper ou algo do tipo) precisa criar novos objetos válidos e apra isso precisa verificar e garantir a invariante. Como esta lógia é da Factory é normal que o Repository utilize a Factory (não o contrário). Um Rpoeisotyr pode também abstrair funções do tipo "procure X, caso não encotnre crie um novo".

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
DavidMichael
Smalltalk

Membro desde: 13/06/2007 09:22:31
Mensagens: 2
Offline

Opa pessoal, tudo bom?

Eu tenho uma dúvida quanto ao reuso dos métodos de "CRUD" no caso, por exemplo, qual seriam as formas mais elegantes de eu nao ter que implementar métodos como Person.get() , ou Person.list() em todos o meus objetos de négocio?
Fabio Kung
JavaEvangelist

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

Acho que fica melhor (em Java) deixar esses métodos no repositório / dao.

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


http://blog.caelum.com.br


Fabio Kung
[WWW] [MSN] [ICQ]
Thiago Senna
Forum Spammer
[Avatar]

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

Olá,

esta discussão está ótima!

TriTonE wrote:Segundo alguns textos que li sobre DDD, os factories servem tanto para CRIAR objetos complexos quanto para RECONSTITUIR objetos (por exemplo, objetos carregados do repositório).

Eu entendi diferente. As factories apenas criam objetos novos enquanto é responsabilidade do repository carregar objetos existentes.

Não sou fã da idéia de reaproveitar as factories dentro do repositório também. Eu preferiria deixar a responsabilidade da contrução do objeto existente no framework ORM. Li este artigo ontem e parece que tornaria isto possível.
Migrating to Spring 2: Part 3 - injecting dependencies into entities

DavidMichael wrote:Eu tenho uma dúvida quanto ao reuso dos métodos de "CRUD" no caso, por exemplo, qual seriam as formas mais elegantes de eu nao ter que implementar métodos como Person.get() , ou Person.list() em todos o meus objetos de négocio?

Quero reforçar esta dúvida. Eu prefiro colocar métodos como get(), list() e find() como sendo estáticos, ou seja, prefiro "Aluno.getAll()" ao invés de "new Aluno().getAll()". Já que estamos falando em OO fica estranho uma instância de aluno conhecer e listar outros alunos que não são ele. Enfim... como vocês tem lidado com isso?

Shoes wrote:Segundo, você não precisaria ter um método para este tipo de coisa, aliás se você tiver muitos métodos assim é sinal que seu design é bem ruim. Você resolve isso com outra dupla: Specification/QueryObject.

Não querendo ser folgado... Mas você possui alguma referência para nos indicar para estudar sobre os padrões Specification e QueryObject? Desde os fundamentos e um exemplo mostrando o caminho das pedras para implementá-los?
Obs: Ainda não pesquisei muito no google mas vou pesquisar com certeza.

Thiago Senna
Meu bog http://www.trsenna.wordpress.com
[Email]
mutano
JavaChild
[Avatar]

Membro desde: 02/08/2006 16:07:54
Mensagens: 126
Localização: Santa Cruz do Sul - RS
Offline

Acabei de ler o tópico desde o início (ótimo, por sinal), mas algumas afirmações me dixaram com dúvida,

pcalcado wrote:... I used to have:

And changed to:

...


Segundo o trecho acima, o padrão Repository pode ocasionar em uma camada a mais no design do sistema, dependendo do caso, tudo bem. Mas o que me deixou em dúvida foi a dependência de RepositoryImpl com DatabaseDao... me parece que os 2 ficam com uma dependência forte, ficando o RepositoryImpl sabendo como os dados são armazenados. Neste caso ele ficaria fora da camada de negócio? De repente este exemplo ficou bem abstraído e eu não entendi direito.

Quanto ao MVC:
pcalcado wrote:Acho que você entendeu errado o Model no MVC, por isso esta confusão. Model em MVC é: -> UserRepository -> Implementação concreta do repositório MySQLUserRepository -> Banco de dados. Tudo isso.


pcalcado wrote:Problema com seu exemplo: Action não tem nada a ver com Repository. Action é MVC e MVC é Camada de Apresentação, estamos falando da integração entre negócios e Persistência.


Também sempre considerei MVC como apresentação, conforme a segunda afirmação, mas a primeira parece dizer o contrário... talvez não tenha ficado claro o que o Philip quiz dizer com a primeira afirmação e se puder esclarecer um pouco...
TriTonE
What is classpath?

Membro desde: 29/07/2005 17:44:07
Mensagens: 6
Localização: Ourinhos - SP
Offline

Thiago Senna wrote:Olá,

esta discussão está ótima!

TriTonE wrote:Segundo alguns textos que li sobre DDD, os factories servem tanto para CRIAR objetos complexos quanto para RECONSTITUIR objetos (por exemplo, objetos carregados do repositório).

Eu entendi diferente. As factories apenas criam objetos novos enquanto é responsabilidade do repository carregar objetos existentes.


Sim, você vai utilizar o repository para carregar um objeto. Quando salvamos objetos no repositório, é comum termos atributos "transientes" (referências para services, repositories etc). Então você acaba tendo que satisfazer as dependências dos objetos carregados dentro do repositório mesmo, como você disse. No entanto, quando criamos novos objetos, TAMBÉM temos que fornecer as dependências.

No caso, faz mais sentido "estender" um pouquinho a responsabilidade dos factories de modo a criar e "remontar" objetos. Dessa forma, seu repositório terá uma referência ao factory que, por sua vez, será utilizado para preencher as dependências necessárias antes de retornar o objeto.

Fazendo desse jeito, teremos a lógica a montagem de objetos (criação e reconstituição) em um único local, o que, ao meu ver, facilita a manutenção.
[WWW] [MSN]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team