Vraptor IOC - Boas práticas

4 respostas
denilsont

Prezados,

Estou trabalhando com o vraptor em um projeto ha alguns meses e a medida que o projeto cresceu surgiram alguns problemas de design.
No ínício percebi que havia as vezes em uma mesma request a injeção da mesma classe no controller e no dao, diante deste cenário, passamos a centralizar a injeção no dao, delegando ao controller o objeto do dao (sendo que o dao estaria injetado no controller).

Controller <- Dao <- OutraClasse
Na arquitetura todo modelo tem um dao, e se é necessário funcionalidades crud, tem um controller também, sempre usando generics pros daos e controllers.

Isto vem funcionando bem, mas como o projeto cresceu muito, começamos a ter referências cíclicas de injeção.
Uma coisa que fizemos é se um controller precisa acessar vários daos, o dao nativo do controller recebe os daos secundários (acho que este é o principal problema).

Andei pesquisando um pouco sobre princípios de dependencia acíclica, mas ainda sim estou um pouco confuso sobre o melhor design pro nosso projeto.

As perguntas são:

  • Está correto injetar no dao de um determinado controlador os daos de outros modelos, assim podendo acessar seus métodos tanto no dao quanto no controller?
  • Não estando correto, como fazer para que as diversas funcionalidades fiquem disponíveis tanto no dao, quanto no controller?
  • Subempacotar os daos por funcionalidade e criar serviços de factory seria adequado (ex.: Criar uma factory que sirva diversos daos, e injetar a factory), e qual o melhor modelo?
  • Como facilitar o teste dos controllers que possuem estas injeções dentro de classes injetadas? O exemplo da documentação não atende pra este caso, pois se fizer um mock de uma classe que recebe recursos injetados, não vai funcionar, teria que instanciar todas na mão.

O VRaptor facilitou muito o trampo neste projeto, mas agora, por usar indiscriminadamente injeções causou alguns problemas que queremos evitar daqui pra frente.
Sugestões são bem vindas.

PS.: Desculpe a quantidade de dúvidas num único post.

4 Respostas

Rafael_Guerreiro

Eu gosto de trabalhar separado por funcionalidade.

Assim, uma tela que serve de consulta para outra coisa não vai ficar junto com o CRUD, mesmo que seja da mesma entidade.

Eu tenho muito mais classes mas tenho tudo mais organizado.

E tem vezes que eu consigo fazer 1 controller e 1 DAO para várias entidades, mas tudo relacionado à mesma funcionalidade…

Lembre sempre: se seu método ou sua classe estão muito grandes, significa que você tem que dividí-los. Se a sua classe está muito difícil de testar, significa que ela está errada.

kadu.m.lino

denilsont:
Prezados,

Estou trabalhando com o vraptor em um projeto ha alguns meses e a medida que o projeto cresceu surgiram alguns problemas de design.
No ínício percebi que havia as vezes em uma mesma request a injeção da mesma classe no controller e no dao, diante deste cenário, passamos a centralizar a injeção no dao, delegando ao controller o objeto do dao (sendo que o dao estaria injetado no controller).

Controller <- Dao <- OutraClasse
Na arquitetura todo modelo tem um dao, e se é necessário funcionalidades crud, tem um controller também, sempre usando generics pros daos e controllers.

Isto vem funcionando bem, mas como o projeto cresceu muito, começamos a ter referências cíclicas de injeção.
Uma coisa que fizemos é se um controller precisa acessar vários daos, o dao nativo do controller recebe os daos secundários (acho que este é o principal problema).

Andei pesquisando um pouco sobre princípios de dependencia acíclica, mas ainda sim estou um pouco confuso sobre o melhor design pro nosso projeto.

As perguntas são:

  • Está correto injetar no dao de um determinado controlador os daos de outros modelos, assim podendo acessar seus métodos tanto no dao quanto no controller?
  • Não estando correto, como fazer para que as diversas funcionalidades fiquem disponíveis tanto no dao, quanto no controller?
  • Subempacotar os daos por funcionalidade e criar serviços de factory seria adequado (ex.: Criar uma factory que sirva diversos daos, e injetar a factory), e qual o melhor modelo?
  • Como facilitar o teste dos controllers que possuem estas injeções dentro de classes injetadas? O exemplo da documentação não atende pra este caso, pois se fizer um mock de uma classe que recebe recursos injetados, não vai funcionar, teria que instanciar todas na mão.

O VRaptor facilitou muito o trampo neste projeto, mas agora, por usar indiscriminadamente injeções causou alguns problemas que queremos evitar daqui pra frente.
Sugestões são bem vindas.

PS.: Desculpe a quantidade de dúvidas num único post.

Vamos Lá! não sei se posso te ajudar da melhor forma! mas…

Não é bom vc injetar um DAO dentro de outro, pois msm que por DI voce acaba criando um acoplamento entre essas classes, o que torna seus objetos mais difíceis de testar, de dar manutençao além de ficar menos legível!

se vc tem a necessidade de usar mais de 1 DAO em uma regra injete os dois no controller msm, ou cria uma camada Service

Controller - > Service - > DAOs === dessa forma vc encapsula melhor a sua funcionalidade

abrass

kadu.m.lino

Outra obs

Separando os DAOs, vc cria testes mais específicos e com mais facilidade

Assim vc pode mockar seus DAOs pra testar o controller, vc apenas vai testar sua regra que está no controller e não o DAO… o DAO vc já sabe que está funcionando… pois vc jah crio testes pra eles

denilsont

pois eh, das duas opções, acho que a idéia de criar uma service realmente é a melhor.
estudando um pouco sobre um artigo do Uncle Bob realmente ele cri a uma camada intermediária para servir os objetos do pacote.

ainda estou engatinhando com tdd por isso estou com um pouco de dúvida, e não usar tdd sempre leva ao design errado, como todos sabem.
mas as dicas foram esclarecedoras.

vlw pessoal.

Criado 23 de janeiro de 2013
Ultima resposta 24 de jan. de 2013
Respostas 4
Participantes 3