Vraptor IOC - Boas práticas

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.

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.

[quote=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.
[/quote]

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

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

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.