Swift Language Tipi di iniezione delle dipendenze


Esempio

Questo esempio mostrerà come utilizzare il pattern di progettazione Dipendenza Iniezione ( DI ) in Swift usando questi metodi:

  1. Iniezione inizializzatore (il termine corretto è Iniezione costruttore, ma poiché Swift ha inizializzatori si chiama iniezione inizializzatore)
  2. Proprietà dell'iniezione
  3. Metodo di iniezione

Esempio di installazione senza DI

    protocol Engine {
        func startEngine()
        func stopEngine()
    }
    
    class TrainEngine: Engine {
        func startEngine() {
            print("Engine started")
        }
        
        func stopEngine() {
            print("Engine stopped")
        }
    }
    
    protocol TrainCar {
    var numberOfSeats: Int { get }
    func attachCar(attach: Bool)
}

class RestaurantCar: TrainCar {
    var numberOfSeats: Int {
        get {
            return 30
        }
    }
    func attachCar(attach: Bool) {
        print("Attach car")
    }
}

class PassengerCar: TrainCar {
    var numberOfSeats: Int {
        get {
            return 50
        }
    }
    func attachCar(attach: Bool) {
        print("Attach car")
    }
}
    
class Train {
    let engine: Engine?
    var mainCar: TrainCar?
}

Iniezione delle dipendenze dell'inizializzatore

Come dice il nome, tutte le dipendenze vengono iniettate attraverso l'inizializzatore della classe. Per iniettare le dipendenze attraverso l'inizializzatore, aggiungeremo l'inizializzatore alla classe Train .

Il corso di formazione ora si presenta così:

class Train {
    let engine: Engine?
    var mainCar: TrainCar?
    
    init(engine: Engine) {
        self.engine = engine
    }
}

Quando vogliamo creare un'istanza della classe Train utilizzeremo l'inizializzatore per iniettare una specifica implementazione del motore:

let train = Train(engine: TrainEngine())

NOTA: il vantaggio principale dell'iniezione dell'inizializzatore rispetto all'iniezione di proprietà è che possiamo impostare la variabile come variabile privata o addirittura renderla costante con la parola chiave let (come abbiamo fatto nel nostro esempio). In questo modo possiamo assicurarci che nessuno possa accedervi o cambiarlo.

Iniezione delle dipendenze delle proprietà

L'utilizzo delle proprietà di DI è ancora più semplice con l'uso di un inizializzatore. Inseriamo una dipendenza PassengerCar dall'oggetto del treno che abbiamo già creato utilizzando le proprietà DI:

train.mainCar = PassengerCar()

Questo è tutto. Il mainCar del nostro treno è ora un'istanza di PassengerCar .

Metodo Iniezione di dipendenza

Questo tipo di iniezione delle dipendenze è un po 'diverso dai precedenti perché non influenzerà l'intero oggetto, ma verrà iniettato solo una dipendenza da utilizzare nell'ambito di uno specifico metodo. Quando una dipendenza viene utilizzata solo in un singolo metodo, di solito non è buono per rendere l'intero oggetto dipendente da esso. Aggiungiamo un nuovo metodo alla classe Train:

func reparkCar(trainCar: TrainCar) {
    trainCar.attachCar(attach: true)
    engine?.startEngine()
    engine?.stopEngine()
    trainCar.attachCar(attach: false)
}

Ora, se chiamiamo il metodo della nuova classe del treno, inietteremo la TrainCar usando l'iniezione della dipendenza del metodo.

train.reparkCar(trainCar: RestaurantCar())