No framework Spring quando queremos fazer alguma injeção de dependência (DI) é comum fazermos por atributos.
@Autowired
private InjectedDependency injectedDependency;
Porém este método tem suas desvantagens e vou dizer quais.
Mas antes vamos escolher uma batida para acompanhar.
Agora sim.
Existem 3 maneiras de se realizar a injeção de dependência no Spring, apesar da documentação, no momento que escrevo, citar apenas duas. A já citada e exemplificada por atributo, através do construtor da classe e por setters métodos.
Pelo construtor:
private InjectedDependency injectedDependency;
@Autowired
public MyDependencyInjection(InjectedDependency injectedDependency) {
this.injectedDependency = injectedDependency;
}
E por setters:
private InjectedDependencyOne injectedDependencyOne;
private InjectedDependencyTwo injectedDependencyTwo;
@Autowired
private void setInjectedDependencyOne(InjectedDependencyOne injectedDependencyOne) {
this.injectedDependencyOne = injectedDependencyOne;
}
@Autowired
private void setInjectedDependencyTwo(InjectedDependencyTwo injectedDependencyTwo) {
this.injectedDependencyTwo = injectedDependencyTwo;
}
A primeira vista realizar a injeção de dependência por atributos parece ser, e é, mais simples e menos verbosa. Uma linha e direto ao ponto(tirando a anotação). Porém nem sempre o simples é o melhor, eis os pontos negativos.
Não permite imutabilidade dos nossos atributos
Nossa injeção não funcionará com atributos da classe que forem declarados como final
, logo perdemos a imutabilidade destes atributos. Com a injeção através dos construtores não perderiamos a imutabilidade destes atributos.
Ferir o S do SOLID
Adicionar dependências a nossa classe por atributos por ser menos verboso pode trazer o problema de nossa classe possuir várias dependências sem nos darmos conta que a classe esta fazendo mais do que deveria, tendo mais de uma responsabilidade ferindo o Single responsibility principle. A injeção através dos construtores nos ajudaria tornando este construtor cheio e mais visível da quantidade de dependências e responsabilidades da classe .
Aqui diria que é mais questão de dar visibilidade que uma refatoração pode ser necessária.
Esconde as dependências
A classe perde a responsabilidade por obter e gerenciar as dependências, deixando a cargo dos containers de injenção de dependência. Neste cenário seria ideal deixar claro, além de ser recomendável quando se usa DI, quais as dependências utilizadas são obrigatórias e quais são opcionais. O que ficaria inviável através de atributos. Utilizando construtores para obrigatórios e setters para opcionais conseguimos.
Acoplamento do container de DI
Como citado anteriormente a responsabilidade agora será dos containers de DI, neste caso containers Spring. O que deixa nosso desenvolvimento acoplado ao container.
Fora do container da aplicação fica mais dificíl utilizar estas dependências. Em um cenário de testes unitários por exemplo, seria necessário instanciar este Spring container(o que alteraria nosso teste unitário para um de integração) e utilizar reflexão
para settar estes atributos.
Utilizando a DI com construtores invés de por atributos, apenas instanciamos estas classes e passamos como nossas dependências.
Conclusão
Realizar a injeção de dependência por construtores ou através de setters apesar de ser mais verboso deixa nosso código mais legível, na minha opinião.
Um dos exemplos seria quando temos um construtor com muito parâmetros, neste caso as dependências, indica que nossa classe faz mas do que deveria e pode caber uma refatoração. Ainda sobre ser tornar o código legível, podemos citar também sobre a obrigatoriedade de uma dependência quando passada através de construtores ou sua opcionalidade quando passada por setteres.
Se você achou que tem um ponto ou vários que não faz sentido comenta ae pra gente debater sobre, uma discussão saúdavel é ótimo para aprender.
Referências que usei
Top comments (0)