Sobes.tech
Middle

Каква е разликата между инверсия на зависимостите и инжектиране на зависимости?

sobes.tech AI

Отговор от AI

Инверсия на зависимостите (Dependency Inversion Principle) е един от принципите SOLID, който гласи:

  1. Модулите от висок ниво не трябва да зависят от модулите от ниско ниво. И двата трябва да зависят от абстракции.
  2. Абстракциите не трябва да зависят от детайлите, детайлите трябва да зависят от абстракциите.

Внедряването на зависимост (Dependency Injection, DI) е шаблон за проектиране, един от начините за реализация на инверсията на зависимостта. То предполага предаване на зависимости (обекти, от които зависи даден клас) отвън, вместо класът да ги създава сам.

Основни разлики:

  • DIC - принцип за проектиране, DI - шаблон за проектиране.
  • DIC - определя как трябва да бъдат отношенията между модули от висок и нисък ниво (зависимост от абстракции).
  • DI - метод, който позволява реализирането на тези отношения. Това е конкретна техника за доставка на зависимости към обект.

Примери за внедряване на зависимости:

  • Внедряване чрез конструктор: Зависимостите се предават чрез конструктора.

    // Swift
    class UserFetcher {
        private let apiService: APIServiceProtocol // Зависимост от абстракция
    
        init(apiService: APIServiceProtocol) { // Внедряване чрез конструктор
            self.apiService = apiService
        }
    
        func fetchUsers() {
            // използване на apiService
        }
    }
    
    protocol APIServiceProtocol {
        // ...
    }
    
  • Внедряване чрез свойство: Зависимостите се установяват чрез публични свойства (често с използване на @IBOutlet или когато зависимостта е опционална).

    // Swift
    class UserController: UIViewController {
        var userFetcher: UserFetcherProtocol? // Зависимост, която може да бъде установена отвън
    
        override func viewDidLoad() {
            super.viewDidLoad()
            userFetcher?.fetchUsers()
        }
    }
    
    protocol UserFetcherProtocol {
        func fetchUsers()
    }
    
  • Внедряване чрез метод: Зависимостите се предават като параметри на методите.

    // Swift
    class DataProcessor {
        func process(data: Data, using parser: DataParserProtocol) { // Зависимост, предадена на метода
            parser.parse(data)
        }
    }
    
    protocol DataParserProtocol {
        func parse(_ data: Data)
    }
    

По този начин, инверсията на зависимостите е целта (намаляване на свързаността чрез абстракции), а внедряването на зависимостите е средство (един от начините за постигане на тази цел).