Princípio de inversão de dependência
Definição
A. Módulos de nível superior não devem depender de módulos de nível inferior. Ambos os tipos de módulos devem depender de abstrações.
B. Abstrações não devem depender de detalhes. Os detalhes devem depender da abstração.
A primeira definição inclui o conceito de “módulo”. Este é um conceito muito importante sem o qual o DIP não pode ser entendido.
módulo - um conjunto logicamente interconectado de elementos funcionais
Para evitar mal-entendidos, considere as definições por exemplo. Digamos que precisamos obter uma lista de livros lidos e exibi-la ao usuário. Para isso, usaremos as classes BooksInteractor e BooksRepository. Colocamos cada uma dessas classes em seu módulo BI e BR, respectivamente. O módulo de classe BooksInteractor depende da classe BooksRepository.
BooksInteractor'y precisa obter uma lista de livros de BooksRepository. O Interactor não se importa em absoluto como o repositório recebe esses dados, o que significa que, neste caso, BooksInteractor é uma abstração de BooksRepository. De acordo com a segunda definição, BooksInteractor (abstração) NÃO deve depender de BooksRepository (implementação). Por outro lado, o repositório deve conhecer o módulo de BI. Então o que acontece: o interator deve estar dentro do repositório? Não, para inverter as dependências, precisamos apenas cobrir o BooksRepository com a interface IBooksRepository e colocar essa interface no módulo de classe BooksInteractor. Agora vamos voltar à 1ª definição de DIP e dar uma olhada no diagrama.
Olha, os módulos de nível superior (módulo BI) não dependem dos módulos de nível inferior (módulo BR). E ambos os módulos dependem de uma abstração (da interface IBooksRepository). Se você captou a magia da inversão de dependência cobrindo um repositório com uma interface, você entende o princípio da inversão de dependência. Parabéns! A parte mais difícil você entende. Você pode ler mais sobre o DIP neste artigo sobre Habré.
Inversão de controle
Estudamos o conceito de "Princípio de Inversão de Dependência". Agora vamos passar para outra inversão - inversão de controle. O conceito em si é muito amplo e na programação pode significar uma de três coisas:
- Inversão de interfaces - delegação da relação entre módulos para uma interface intermediária. Onde isso se aplica? Por exemplo, no DIP, que estudamos anteriormente.
- — (, DI/IOC ).
- — , . , , — Android . Activity Fragment, .
Dependency Injection
A injeção de dependência é um mecanismo para passar suas dependências para uma classe. Você sempre se depara com isso quando precisa passar uma dependência para outra classe. Existem várias maneiras de injetar dependências: por meio de um construtor (Injeção de Construtor), por meio de um método (Injeção de Método) e por meio de uma propriedade (Injeção de Propriedade). Cada um desses métodos é usado para seus próprios fins. Mas aqui é importante entender que a injeção de dependência é apenas passar uma dependência para um construtor, método ou propriedade.
Considerando casos extremos
- Poderia haver DI sem IoC e DIP? Sim talvez. Criamos uma instância de uma classe A concreta e a passamos para um objeto da classe B por meio de um construtor, método ou propriedade.
- Poderia haver DIP sem IoC? Não, o DIP é uma maneira de implementar a inversão de interface no IoC.
- Pode haver DIP sem DI? Sim, podemos ligar os módulos inferiores à interface. As classes do módulo superior funcionarão com a abstração da interface, mas a implementação concreta da classe do módulo inferior será criada no construtor do módulo superior.
Você pode descobrir as diferenças entre DIP, DI e IoC de outros autores aqui e aqui .
Seus comentários e feedbacks serão bem-vindos!