Sobes.tech
Middle

Qual é a diferença entre inversão de dependências e injeção de dependências?

sobes.tech IA

Resposta da IA

A inversão de dependência (Princípio da Inversão de Dependências) é um dos princípios SOLID, que afirma:

  1. Os módulos de nível superior não devem depender de módulos de nível inferior. Ambos devem depender de abstrações.
  2. As abstrações não devem depender dos detalhes, os detalhes devem depender das abstrações.

A injeção de dependências (Dependency Injection, DI) é um padrão de projeto, uma das formas de implementar a inversão de dependência. Ela implica passar as dependências (objetos dos quais uma classe depende) de fora, em vez de a classe criá-las por si mesma.

Principais diferenças:

  • DIC - princípio de projeto, DI - padrão de projeto.
  • DIC - define como devem ser as relações entre módulos de alto e baixo nível (dependência de abstrações).
  • DI - método que permite implementar essas relações. É uma técnica concreta para fornecer dependências a um objeto.

Exemplos de injeção de dependências:

  • Injeção por construtor: As dependências são passadas através do construtor.

    // Swift
    class UserFetcher {
        private let apiService: APIServiceProtocol // Dependência de abstração
    
        init(apiService: APIServiceProtocol) { // Injeção através do construtor
            self.apiService = apiService
        }
    
        func fetchUsers() {
            // uso de apiService
        }
    }
    
    protocol APIServiceProtocol {
        // ...
    }
    
  • Injeção por propriedade: As dependências são estabelecidas através de propriedades públicas (frequentemente usando @IBOutlet ou quando a dependência é opcional).

    // Swift
    class UserController: UIViewController {
        var userFetcher: UserFetcherProtocol? // Dependência que pode ser estabelecida de fora
    
        override func viewDidLoad() {
            super.viewDidLoad()
            userFetcher?.fetchUsers()
        }
    }
    
    protocol UserFetcherProtocol {
        func fetchUsers()
    }
    
  • Injeção por método: As dependências são passadas como parâmetros de métodos.

    // Swift
    class DataProcessor {
        func process(data: Data, using parser: DataParserProtocol) { // Dependência passada ao método
            parser.parse(data)
        }
    }
    
    protocol DataParserProtocol {
        func parse(_ data: Data)
    }
    

Assim, a inversão de dependência é o objetivo (redução do acoplamento através de abstrações), e a injeção de dependência é o meio (uma das formas de alcançar esse objetivo).