Injeção de dependencias por @anotações, não é colocar dependências anyway ao código?

13 respostas
MrDataFlex

Uma vez que é necessário fazer:

@Injection(classImpl=MyImplementationClass.class) private MyInterfaceClass clazz;

Este MyImplementationClass necessariamente não deveria aparecer ai …

pregar configuração programática ou por anotações é MANTER dependências no código ou não, afinal… falam tão mal dos XMLs que bateu esta duvida…

valeu

13 Respostas

sergiotaborda

MrDataFlex:
Uma vez que é necessário fazer:

@Injection(classImpl=MyImplementationClass.class) private MyInterfaceClass clazz;

Este MyImplementationClass necessariamente não deveria aparecer ai (por mais que seja apenas um apontamento para seu binário…)…

pregar configuração programática ou por anotações é acoplar código ou não, afinal… falam tão mal dos XMLs que bateu esta duvida…

Em tese não é acoplamento. Mas ha uma dependencia. Se o nome da classe de implmentação mudar, teremos que recompilar a classe com o codigo acima. Realmente é um tiro no pé e não é diferente disto

private MyInterfaceClass clazz = new MyImplementationClass();
MrDataFlex

sergiotaborda:
MrDataFlex:
Uma vez que é necessário fazer:

@Injection(classImpl=MyImplementationClass.class) private MyInterfaceClass clazz;

Este MyImplementationClass necessariamente não deveria aparecer ai (por mais que seja apenas um apontamento para seu binário…)…

pregar configuração programática ou por anotações é acoplar código ou não, afinal… falam tão mal dos XMLs que bateu esta duvida…

Em tese não é acoplamento. Mas ha uma dependencia. Se o nome da classe de implmentação mudar, teremos que recompilar a classe com o codigo acima. Realmente é um tiro no pé e não é diferente disto

private MyInterfaceClass clazz = new MyImplementationClass();

Exatamente nisso que me refiro amigo.

L

O fato de botar o nome da classe que se quer ser injetado é um problema, se fosse apenas @Injection e nada mais, ficaria mais desacoplado.

Mas, por falar nisso, esse @Injection faz parte de algum framework?

MrDataFlex

Leonardo3001:
O fato de botar o nome da classe que se quer ser injetado é um problema, se fosse apenas @Injection e nada mais, ficaria mais desacoplado.

Mas, por falar nisso, esse @Injection faz parte de algum framework?

não, foi apenas exemplar… mas sua idéia tbm é usada, quando falamos de CoC (convertion over configuration)… o mesmo sendo um artefato de escolha e gosto…

Paulo_Silveira

Lembre-se que a frase é 'baixo acoplamento". Nunca da pra voce fazer 0 acoplamento.

Voce ta falando do GUICE certo? (que tem @Inject)

No Guice tem como voce definir implementacoes default por exemplo, entao ai bastaria o @Inject, e nem precisaria citar a classe concreta. O dia que precisasse mudar todas as implementacoes, mudaria só em um lugar. Alem de que a injecao tambem serve pra controlar ciclo de vida e outras coisas, nao apenas para isolar a implementacao.

De uma maneira ou de outra em algum lugar voce vai ter de escrever o nome da implementacao: no XML, na anotacao, no codigo configurando ou mesmo no codigo (dando new explicitamente ate!!!). O importante é que voce consiga isolar isso… nao que voce va remover isso completamente do seu projeto (seria zero acoplamento, mas o software nao funcionaria :)).

Paulo_Silveira

sergiotaborda:

Em tese não é acoplamento. Mas ha uma dependencia. Se o nome da classe de implmentação mudar, teremos que recompilar a classe com o codigo acima. Realmente é um tiro no pé e não é diferente disto

private MyInterfaceClass clazz = new MyImplementationClass();

mas veja bem… isso não é ruim! nao acho um tiro no pe! É 100x melhor que declarar pela MyImplementationClass!!! E a partir dai refatorar para um framekwork de IoC é facinho.

MrDataFlex

Paulo Silveira:
Lembre-se que a frase é 'baixo acoplamento". Nunca da pra voce fazer 0 acoplamento.

Voce ta falando do GUICE certo? (que tem @Inject)

No Guice tem como voce definir implementacoes default por exemplo, entao ai bastaria o @Inject, e nem precisaria citar a classe concreta. O dia que precisasse mudar todas as implementacoes, mudaria só em um lugar. Alem de que a injecao tambem serve pra controlar ciclo de vida e outras coisas, nao apenas para isolar a implementacao.

De uma maneira ou de outra em algum lugar voce vai ter de escrever o nome da implementacao: no XML, na anotacao, no codigo configurando ou mesmo no codigo (dando new explicitamente ate!!!). O importante é que voce consiga isolar isso… nao que voce va remover isso completamente do seu projeto (seria zero acoplamento, mas o software nao funcionaria :)).

Olá Paulo, não estava falando do GUICE (o qual não conheço, mas obrigado pela citação!) e entendi o que você quis dizer… era isso, valeu! topico resolvido :wink:

sergiotaborda

Paulo Silveira:
sergiotaborda:

Em tese não é acoplamento. Mas ha uma dependencia. Se o nome da classe de implmentação mudar, teremos que recompilar a classe com o codigo acima. Realmente é um tiro no pé e não é diferente disto

private MyInterfaceClass clazz = new MyImplementationClass();

mas veja bem… isso não é ruim! nao acho um tiro no pe! É 100x melhor que declarar pela MyImplementationClass!!! E a partir dai refatorar para um framekwork de IoC é facinho.

Todo o objetivo de usar DI (Dependecy Injection) é não fornecer as dependencias explicitamente. No momento que a classe de implementação faz parte do import da classe usuária já temos uma dependencia que nenhum DI pode alterar. O nome da classe de implementação tem realmente que ficar em algum lugar, mas o ponto é que não pode ficar na classe que a usa. Por isso temos interfaces e por isso temos DI. (IoC são outros 500)

É bom lembrar que DI não é mais do que uma Factory supervalorizada. Se a classe que usa a factory já sabe a classe que a factory vai retornar que utilidade tem a factory ?

saoj

Vc tem que fazer a escolha:

  • configuração centralizada num lugar só: pode ser xml, Java, BeanShell, Groovy, etc.

  • configuração espalhada via annotations.

Eu prefiro a primeira. Outros vão perferir a segunda.

Annotations acopla sim, mas em 99% das vezes isso não é um grande problema. Algumas pessoas vão preferir manter a configuração espalhada e próxima ao que ela se refere do que centralizada num único arquivo que acaba ficando grande.

Se vc preferir configuração centralizada e código totalmente desacoplado, dá uma olhada nesse meu blog aqui: http://blogs.mentaframework.org/posts/list/14.page

Paulo_Silveira

Como assim espalhada via anotacoes? Se voce fizer certinho, so precisa mexer em UM lugar, que é o lugar onde voce configurou qual dependencia injetar (que é o que o Sergio citou acima como a vantagem em relacao a apenas o uso de interface, e concordo totalmente). Se quando eu tiver de alterar TODO o sistema eu precisar alterar apenas UM lugar, voce diria que essa configuracao esta espalhada? Claro que nao…

No GUICE essa configuracao centralizada pode ser feita por anotacoes ou programativamente (ou XML se voce inventar). O Uso de anotacoes nao obriga voce a ter de espalhar configuracoes de implementacao.

Alem disso, no seu link voce fala de codigo completamente desacoplado, sendo que um Map<String, Object> é a forma mais comum que as pessoas acabam utilizando para tirar tipagem do seu codigo. Voce vai acabar com um codigo totalmente acoplado a strings (o classico SOP: string oriented programming) e cheio de castings… uma das poucas vantagens do java é ser estaticamente tipada, e voce perde isso. Sem testes unitarios entao isso vira um inferno. Todo desacoplamento tem um preco, ou uma outra acoplagem.

saoj

Interessante suas colocações…

Se vc usa só o @Injection e configura o tipo que será injetado num lugar único, como Guice, então concordo. Mas como o cara citou existe exemplos onde o cara configura ali mesmo o tipo que será injetado, ou seja, ela está espalhando a configuração pelo código inteiro ao invés de centralizar tudo num único lugar.

@Injection(classImpl=MyImplementationClass.class)  
private MyInterfaceClass clazz;

Outra coisa que eu vejo espalhado é configurações de action, como página de destino, filtros, validação, etc. Não é o fim do mundo. Eu acho que fica mais claro colocar a configuração perto do que ela se refere, mas há a desvantagem de acoplar o seu código todo a um monte de anotações e configurações.

Eu acho (opinião pessoal minha) que fica mais limpo e organizado colocar toda a configuração num único lugar centralizado. Facilita o auto-reload, não força um full-rebuild quando a configuração mudar, e o código fica totalmente independente do framework, etc.

No caso da validação eu acabo me rendendo e acoplando a lógica de validação a minha action, fazendo ela implementar Validatable. Poderia ficar ainda mais limpo e desacoplado utilizando um filtro separado para tal, mas nesse caso eu prefiro a comodidade e praticidade de fazer isso dentro da action mesmo.

É uma questão de escolha. Não existe certo ou errado aqui, acredito eu. Se o cara quer total desacoplamento, que seja…

É melhor vc se acoplar a um Map<String,Object> do que ser acoplar a um HttpSession ou a um org.myframework.core.Session da vida, concorda?

Não sei se eu exemplifiquei isso no meu blog, mas nada te impede também de injetar os valores da sessão diretamente na sua action como variáveis de instância.

Paulo_Silveira

na minha opiniao, muito melhor!

Marcio_Duran

:thumbup: Um pouco de Teoria:

[size=18]Kathy Sierra
Bert Bates [/size]

O acoplamento refere-se ao nível em que uma classe conhece ou usa membros de uma outra classe.
O acoplamento fraco é o estado desejável para classes bem encapsuladas, que minimizam as referências uma ás outras e limitam a extensão do uso da API.
O acoplamento forte é o estado indesejável de se ter classes que desobedecem as regras do acoplamento fraco.

Criado 19 de março de 2008
Ultima resposta 19 de mar. de 2008
Respostas 13
Participantes 6