Sobes.tech
Middle

Qual è la differenza tra inversione delle dipendenze e injection delle dipendenze?

sobes.tech AI

Risposta dell'AI

L'inversione delle dipendenze (Principio di Inversione delle Dipendenze) è uno dei principi SOLID, che afferma:

  1. I moduli di livello superiore non devono dipendere dai moduli di livello inferiore. Entrambi devono dipendere da astrazioni.
  2. Le astrazioni non devono dipendere dai dettagli, i dettagli devono dipendere dalle astrazioni.

L'iniezione delle dipendenze (Dependency Injection, DI) è un pattern di progettazione, uno dei modi per implementare l'inversione delle dipendenze. Implica il passaggio delle dipendenze (oggetti di cui una classe dipende) dall'esterno, invece che la classe le crei da sola.

Principali differenze:

  • DIC - principio di progettazione, DI - pattern di progettazione.
  • DIC - definisce come devono essere le relazioni tra moduli di alto e basso livello (dipendenza da astrazioni).
  • DI - metodo che permette di implementare queste relazioni. È una tecnica concreta per fornire dipendenze a un oggetto.

Esempi di iniezione delle dipendenze:

  • Iniezione tramite costruttore: Le dipendenze vengono passate attraverso il costruttore.

    // Swift
    class UserFetcher {
        private let apiService: APIServiceProtocol // Dipendenza da astrazione
    
        init(apiService: APIServiceProtocol) { // Iniezione tramite il costruttore
            self.apiService = apiService
        }
    
        func fetchUsers() {
            // utilizzo di apiService
        }
    }
    
    protocol APIServiceProtocol {
        // ...
    }
    
  • Iniezione tramite proprietà: Le dipendenze vengono impostate tramite proprietà pubbliche (spesso usando @IBOutlet o quando la dipendenza è opzionale).

    // Swift
    class UserController: UIViewController {
        var userFetcher: UserFetcherProtocol? // Dipendenza che può essere impostata dall'esterno
    
        override func viewDidLoad() {
            super.viewDidLoad()
            userFetcher?.fetchUsers()
        }
    }
    
    protocol UserFetcherProtocol {
        func fetchUsers()
    }
    
  • Iniezione tramite metodo: Le dipendenze vengono passate come parametri dei metodi.

    // Swift
    class DataProcessor {
        func process(data: Data, using parser: DataParserProtocol) { // Dipendenza passata al metodo
            parser.parse(data)
        }
    }
    
    protocol DataParserProtocol {
        func parse(_ data: Data)
    }
    

In questo modo, l'inversione delle dipendenze è l'obiettivo (ridurre l'accoppiamento tramite astrazioni), e l'iniezione delle dipendenze è il mezzo (una delle modalità per raggiungere questo obiettivo).