DDD + IoC\DI + frameworks web + invariantes de um objeto  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Imaginem que você esta utilizando algum framework web moderno que trabalha com Pojo e coloca na sua "action" um pojo preenchido com os dados da request.
Ao mesmo tempo você esta utilizando domain driven design e algum framework parrudo de IoC\DI com o Spring.
Usando DDD, você normalmente não tera coisas como noticiaService.publica(noticia) e sim noticia.publica().
No exemplo da noticia, teriamos um código mais ou menos assim:



Noticia é um entity, noticiaRepository é uma interface de um Repository e notificacaoPublicacaoService é uma interface para um Service (ok, não é o melhor exemplo de service).

Usando um container DI\IoC, como o Spring, eu deixaria a instanciação do noticiaRepository e do notificacaoPublicacaoService gerenciadas pelo container IoC\DI (usando o Spring eu posso inclusive cuidar de integração com JPA e outras coisas).

Neste caso, notificacaoPublicacaoService e noticiaRepository são invariantes do objeto noticia, ou seja, para utilizar o objeto noticia eu preciso que esses caras estejam instanciados e "setados" no objeto noticia.

A questão é, como estou usando um framework web moderno baseado em Pojo, o objeto noticia é instanciado pelo framework web. Qual a melhor maneira de injetar as invariantes gerenciadas pelo container IoC\DI nas entities?


Algumas opções, boas e "não tão boas":

1) No construtor da Entity chamar a API do container IoC\DI para preencher as invariantes



2) Fazer a Entity ser gerenciada pelo container IoC\DI e deixar que ele preencha as invariantes e fazer algum gato no framework web para este usar a Entity gerenciada pelo container IoC\DI:

O que vocês tem usado? Alguém já fez isso com JSF+Spring? Recomendam algum outro framework?

This message was edited 1 time. Last update was at 09/03/2009 00:33:31




Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
pcalcado
Moderador
[Avatar]

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

Rubem Azenha wrote:
Usando DDD, você normalmente não tera coisas como noticiaService.publica(noticia) e sim noticia.publica().


Não necessariamente. Você terá o que fizer sentido na sua linguagem de domínio, se isto fizer sentido então...

Rubem Azenha wrote:
1) No construtor da Entity chamar a API do container IoC\DI para preencher as invariantes


Eu realmente não gosto desta idéia. Acoplar uma Entity com infra-estrutura é pedir para ter problemas.

Rubem Azenha wrote:
2) Fazer a Entity ser gerenciada pelo container IoC\DI e deixar que ele preencha as invariantes e fazer algum gato no framework web para este usar a Entity gerenciada pelo container IoC\DI:


Não sei nada de JSF mas este bean não devia ser a Noticia em si e sim uma Facotory de notícias. Teu framework não te deixa usar uma Factory para objetos? Se não deixar você pode utilizar um daqueles factory beans do Spring, não?


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]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

pcalcado wrote:
Não necessariamente. Você terá o que fizer sentido na sua linguagem de domínio, se isto fizer sentido então...

Tem razão, mas vamos dizer que neste caso faz sentido uma construção assim.

pcalcado wrote:
Eu realmente não gosto desta idéia. Acoplar uma Entity com infra-estrutura é pedir para ter problemas.

Eu tenho esse receito também.

pcalcado wrote:
Não sei nada de JSF

No meu caso é JSF, mas o principio se aplica a qualquer framework web java que preenche um pojo com os dados da request.

pcalcado wrote:
mas este bean não devia ser a Noticia em si e sim uma Facotory de notícias. Teu framework não te deixa usar uma Factory para objetos? Se não deixar você pode utilizar um daqueles factory beans do Spring, não?

Eu também acho que a melhor opção é deixar que uma Factory (do Spring ou criada por você mesmo) preencha as invariantes "complexas" como o Repository e os Services cascudos. Não sei se é tão fácil fazer os frameworks web trabalharem com isso.

Alias, isso fica pior quando se trata de um objeto recuperado pelo banco de dados usando um ORM como Hiberante! Por acaso o Hibernate deixa você usar uma Entity (classe anotada com @Entty neste caso) criada por uma Factory? Ou vou ter que fazer alguma Gambi com Listeners Post-Load?



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
Sergio Lopes
Moderador
[Avatar]

Membro desde: 17/11/2003 00:22:10
Mensagens: 1368
Localização: São Paulo - SP
Offline

Definitivamente chamar as coisas do container pra mim não só é feio pelo DDD como fere IoC. Má ideia.

Aqui na Caelum, eu faço a segunda coisa: magia negra (negrinha na verdade) no framework pra injetar as coisas. No caso, uso VRaptor e escrevo um plugin que roda para interceptar o miolo entre o bean ser populado pelo framework e a action ser chamada.

No VRaptor, é um saco fazer essa interceptação antes da chamada da action, como é no Struts, num servlet Filter e provavelmente em muitos outros frameworks. No JSF, isso deve ser ridiculo de fazer com um PhaseListener executando antes do INVOKE_APPLICATION. (ah como eu queria que o vraptor tivesse algo como phase listeners .

Para injetar coisas nas entities do Hibernate, dá uma olhada no hinjector do Fabio Kung: http://sf.net/project/hinjector

Sérgio Lopes - twitter: @sergio_caelum - blog pessoal: sergiolopes.org
Curso Java | Apostilas Java | Arquitetura Java | Curso Rails
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Interessante Sérgio!
Vou tentar algo assim.

No caso do hinjector eu já tinha dado uma olhada mas ele serviria para injetar as invariantes DEPOIS do objeto ter sido criado, o ideal era fornecer para o Hibernate um objeto com as invariantes já preenchidas.

Não sei se não procurei direito, mas é incrível como este tipo de dúvida não foi muito discutida\documentada...



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
boaglio
Moderador
[Avatar]

Membro desde: 09/09/2002 21:23:39
Mensagens: 1865
Localização: Sampa City
Offline


No curso que fiz de JSF com o Fabio Kung na Caelum, ele mostrou um esquema de criar fábricas e declarar no seu faces-config...

Na ocasião não discutimos muito essa prática, mas me pareceu bem interessante.


 

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de Java via MP!
[WWW]
urubatan
Moderador
[Avatar]

Membro desde: 21/09/2002 10:31:26
Mensagens: 2481
Localização: Porto Alegre/RS
Offline

na minha opinião AOP seria a melhor pedida ...
por exemplo, se tu compilar tudo com o AspectJ o spring pode injetar dependencias automaticamente nos POJOs de Dominio

As duas opções que tu colocou eu não cheguei a gostar de nenhuma, exceto se tu estiver trabalhando com o JBoss Seam, ai é só dizer que o POJO é um PAJO (Plain Annotated Java Object) e uma Entity com escopo definido que o Seam gerencia isto para ti (uma das opções mais elegantes na minha opinião, mas usa AOP como eu sugeri antes )

E fora isto, uma factory de beans de dominio seria a melhor opção na minha opinião

[]'s
Rodrigo Urubatan
http://www.urubatan.com.br
Melhor livro de RoR do brasil: http://livro.urubatan.com.br
[WWW]
Leonardo3001
GUJ Ranger

Membro desde: 04/07/2007 18:28:58
Mensagens: 975
Offline

No caso de JSF, os managed beans podem ser beans do Spring. Basta uma configuração explicada aqui.

Havia uma configuração que permitia a injeção de dependências mesmo que você desse new. Usava alguma coisa de AspectJ. Mas infelizmente, me fugiu à memória e não sei mais como se faz.

Leonardo Veríssimo
-------------------------------------------------
Objectzilla
[WWW]
Thiago Senna
GUJ Master
[Avatar]

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

Olá Rubem,

Eu também acho AOP uma boa pedida. O spring dá um bom suporte para isso usando a annotation @Configurable. Dê uma procurada

Outra opção não muito conhecida mas muito show de bola é utilizar instrumentação. Não manjo bulufas, mas o Salve (http://code.google.com/p/salve/) faz isso pra você.


Espero que ajude!
[Email]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Thiago Senna wrote:Olá Rubem,

Eu também acho AOP uma boa pedida. O spring dá um bom suporte para isso usando a annotation @Configurable. Dê uma procurada

Outra opção não muito conhecida mas muito show de bola é utilizar instrumentação. Não manjo bulufas, mas o Salve (http://code.google.com/p/salve/) faz isso pra você.


Espero que ajude!


Depois de algum tempo...

Thiago, acabei não vendo a sua excelente dica com @Configurable e perdi um tempão buscando como fazer isso e acabei achando essa dica em outro lugar
Mas valeu, a dica foi excelente, o @Configurable funcionou muito bem com os meus Pojos!



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
Thiago Senna
GUJ Master
[Avatar]

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

Rubem Azenha wrote:
Thiago Senna wrote:Olá Rubem,

Eu também acho AOP uma boa pedida. O spring dá um bom suporte para isso usando a annotation @Configurable. Dê uma procurada

Outra opção não muito conhecida mas muito show de bola é utilizar instrumentação. Não manjo bulufas, mas o Salve (http://code.google.com/p/salve/) faz isso pra você.


Espero que ajude!


Depois de algum tempo...

Thiago, acabei não vendo a sua excelente dica com @Configurable e perdi um tempão buscando como fazer isso e acabei achando essa dica em outro lugar
Mas valeu, a dica foi excelente, o @Configurable funcionou muito bem com os meus Pojos!


Opa, que bom!
[Email]
dbconrado
Entusiasta Java
[Avatar]

Membro desde: 17/12/2008 12:52:16
Mensagens: 20
Offline

os métodos dentro de um objeto deveriam depender apenas de seus atributos, não é?

Então, como o método publica() utiliza recursos externos ao objeto Noticia (repository e service), isto meio que fere o parágrafo anterior.

Este método traz à classe Noticia as responsabilidades de persistência e de notificação. Logo, fere o SRP.

Como AOP veio para ajudar na modularização de interesses, concordo com todos que disseram que esta tecnologia é uma boa pedida.

Por favor, corrijam-me se eu estiver errado.
Obrigado

DB
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team