Padrão de Injeção de Dependência
O padrão de injeção de dependência visa remover dependências desnecessárias entre as classes ou torná-las mais suaves e ter um design de software que seja fácil de manter e evoluir.
Em um dado post, falei sobre a inversão de controle ou inversão de dependência, que é uma técnica utilizada para diminuir o acoplamento entre classes. Abordamos como o alto acoplamento pode prejudicar o design de uma arquitetura, tornar a sua manutenção custosa e até mesmo dificultar a sua evolução. Hoje irei falar sobre um pattern chamado Injeção de Dependência, que é na verdade uma das formas de se fazer a inversão de controle e assim, garantir um baixo acoplamento em uma cadeia de classes.
Antes de nos aprofundarmos no padrão, temos que entender que quando falamos em “injetar” uma dependência, a grosso modo, nada mais é do que passar uma classe que será utilizada para uma classe que irá consumi-la. O padrão de injeção de dependência trabalha baseado em abstrações, sejam elas classes abstratas ou interfaces. Se pudéssemos citar um “lema”, este seria: programe para uma interface e nunca para uma implementação. E este “lema” realmente faz diferença quando queremos diminuir o acoplamento entre as classes do nosso modelo. Podemos trabalhar com a injeção de dependência de três formas: injeção por construtor (constructor injection); injeção por propriedade ou getters e setters no caso do Java ( setter injection ); e injeção por interface ( interface injection ). Observe o exemplo abaixo:
No exemplo acima, a classe Autor é passada para a classe Artigo pelo construtor, mostrando claramente um exemplo de injeção via construtor ( Constructor Injection ), mas o detalhe do exemplo acima é que embora tenhamos a injeção de dependência, não temos a inversão de controle, pois existe uma dependência da classe Artigo para a classe concreta de Autor , caracterizando um alto acoplamento. E como não é este o cenário que desejamos, iremos modificá-lo. Observe abaixo:
No exemplo acima, tendo sido feita a correção, já temos tanto a injeção de dependência quanto a inversão de controle. O objetivo deste exemplo é mostrar que podemos ter a injeção de dependência sem inversão de controle, mesmo que não seja o nosso cenário desejado, e até mesmo para que tenhamos cuidado na hora de colocar em prática o padrão. O padrão de injeção de dependência é baseado em outro padrão chamado Builder. O Builder será responsável por construir para nós os objetos e armazená-los em algum lugar. É aí que entra em ação o container, que é justamente o lugar onde os objetos construídos serão armazenados. A definição mais simples para o container é que ele é um objeto que pode armazenar outros objetos dentro dele. Para ficar mais claro e até mais fácil de entender como funciona a injeção de dependência, observe o diagrama abaixo:
O que o diagrama acima mostra é o seguinte: está sendo passada a responsabilidade de criar um objeto para o builder, indicando a ele qual é a interface que nós desejamos. Ele cria o objeto que implementa a interface e injeta esta dependência na classe Cliente. E aí está a inversão de controle: ao invés da classe cliente saber qual classe concreta ela precisa utilizar, ela delega isto para outra classe que, além de retornar a implementação apropriada para aquela interface, ainda injeta a dependência. Com isto, quebramos o forte acoplamento e invertemos a dependência, e ao invés de depender de uma classe concreta, passamos a depender de uma abstração, passando a ter um cenário desacoplado, de fácil manutenção e evolução. Pessoal, espero tenham gostado do post e em breve estaremos falando sobre o Unity Application Block, que é um framework para se trabalhar com injeção de dependência. Com exemplos práticos, vamos colocar a mão na massa e extrair o máximo possível deste padrão e ter uma arquitetura mais robusta e madura. Um forte abraço e até a próxima.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo