依賴注入型別

此示例將演示如何使用以下方法在 Swift 中使用依賴注入( DI )設計模式:

  1. 初始化注入 (正確的術語是建構函式注入,但由於 Swift 具有初始化程式,因此稱為初始化程式注入)
  2. 屬性注入
  3. 方法注入

沒有 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?
}

初始化依賴注入

顧名思義,所有依賴項都是通過類初始化程式注入的。要通過初始化程式注入依賴項,我們將初始化程式新增到 Train 類。

火車課現在看起來像這樣:

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

當我們想要建立 Train 類的例項時,我們將使用初始化器來注入特定的 Engine 實現:

let train = Train(engine: TrainEngine())

注意: 初始化器注入與屬性注入的主要優點是我們可以將變數設定為私有變數,或者甚至使用 let 關鍵字使其成為常量(正如我們在示例中所做的那樣)。這樣我們就可以確保沒有人可以訪問它或更改它。

屬性依賴注入

DI 使用屬性甚至比使用初始化程式更簡單。讓我們使用屬性 DI 將已經建立的列車物件注入 PassengerCar 依賴關係:

train.mainCar = PassengerCar()

而已。我們的火車的 mainCar 現在是一個 PassengerCar 例項。

方法依賴注入

這種型別的依賴注入與前兩種有點不同,因為它不會影響整個物件,但它只會注入一個依賴項,以便在一個特定方法的範圍內使用。當依賴關係僅在單個方法中使用時,通常不能使整個物件依賴於它。讓我們為 Train 類新增一個新方法:

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

現在,如果我們呼叫新的 Train 類方法,我們將使用方法依賴注入注入 TrainCar

train.reparkCar(trainCar: RestaurantCar())