Zastrzyk zależności

Dec 29 2022
DI to technika szeroko stosowana w programowaniu oprogramowania. Nawet Google zaleca DI programistom Androida, Android ma do tego celu biblioteki takie jak Dagger, Hilt.

DI to technika szeroko stosowana w programowaniu oprogramowania. Nawet Google zaleca DI programistom Androida, Android ma do tego celu biblioteki takie jak Dagger, Hilt. DI zapewnia następujące korzyści:

  1. Ponowne użycie kodu
  2. Łatwość refaktoryzacji
  3. Łatwość testowania

Wstrzykiwanie zależności to technika, która pozwala na oddzielenie obiektów od obiektów, od których są zależne. Weźmy przykład implementacji DI w iOS.

class HTTPClient {
    func downloadFrom(url: URL) {
        //download data from remote
    }
}

class DataDownload {
    let client = HTTPClient()
    
    func getData(url: URL) {
        client.downloadFrom(url: url)
    }
}

class client {
    let dataDownload: DataDownload
    
    init() {
        self.dataDownload = DataDownload()
        self.dataDownload.getData(url: URL(string: "https://any_http_url.com")!)
    }
}

class FTPClient {
    func downloadFrom(url: URL) {
        //download data from remote
    }
}

class DataDownload {
    let client = FTPClient()
    
    func getData(url: URL) {
        client.downloadFrom(url: url)
    }
}

class client {
    let dataDownload: DataDownload
    
    init() {
        self.dataDownload = DataDownload()
        self.dataDownload.getData(url: URL(string: "https://any_ftp_url.com")!)
    }
}

protocol RemoteClient {
    func downloadFrom(url: URL)
}

class FTPClient: RemoteClient {
    func downloadFrom(url: URL) {
        //download data from remote
    }
}

class DataDownload {
    let client: RemoteClient
    
    init(client: RemoteClient) {
        self.client = client
    }
    
    func getData(url: URL) {
        client.downloadFrom(url: url)
    }
}

class Client1 {
    let dataDownload: DataDownload
    
    init() {
        self.dataDownload = DataDownload(client: FTPClient())
        self.dataDownload.getData(url: URL(string: "https://any_ftp_url.com")!)
    }
}

class Client2 {
    let dataDownload: DataDownload
    
    init() {
        self.dataDownload = DataDownload(client: HTTPClient())
        self.dataDownload.getData(url: URL(string: "https://any_htttp_url.com")!)
    }
}

RemoteClientjest wstrzykiwany DataDownloadz kompozytora/asemblera Client1i Client2. Oddziela również kod. Teraz możemy je przetestować w separacji bez spełniania niechcianej zależności. Niektóre zalety powyższego refaktoryzacji kodu

  1. Łatwość w testowaniu.
  2. Szybszy rozwój nowych funkcji.
  3. Poprawiony czas kompilacji Xcode (napiszę o tym osobny blog).
  4. Oszczędność czasu i pieniędzy.
  1. Wstrzyknięcie konstruktora (wyjaśnione powyżej)
  2. Wstrzyknięcie funkcji
  3. Zastrzyk nieruchomości

class ChildViewController: UIViewController {
    func viewDidLoad() { }
    func viewWillAppear() { }
    func viewDidAppear() { }

    func getDataFrom(_ client: RemoteClient, url: URL) {
        client.downloadFrom(url: url)
    }
}

class ParentViewController: UIViewController {
    func viewDidLoad() { }
    func viewWillAppear() { }
    func viewDidAppear() { }

    func present() {
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc = storyboard.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
        vc.getDataFrom(client: HTTPClient(), url: URL(string:"https://any-url.com")!)
    }
}

Wstrzykiwanie właściwości: HTTPClient jest przekazywany jako Wstrzykiwanie właściwości do var client.

class ChildViewController: UIViewController {
    var client: RemoteClient?

    func viewDidLoad() { }
    func viewWillAppear() { }
    func viewDidAppear() { }

    func getDataFrom(url: URL) {
        client.downloadFrom(url: url)
    }
}

class ParentViewController: UIViewController {
    func viewDidLoad() { }
    func viewWillAppear() { }
    func viewDidAppear() { }

    func present() {
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc = storyboard.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
        vc.client = HTTPClient()
    }
}

Mam nadzieję, że to pomoże! Jeśli spodobał Ci się ten artykuł i chcesz przeczytać więcej niesamowitych artykułów, śledź mnie tutaj i okaż swoje wsparcie, ponieważ motywuje mnie to do pisania więcej.

Podziel się swoją opinią, aby ulepszyć treść i następny temat, który chcesz zbadać.

Dziękuję wszystkim za przeczytanie, szczęśliwego kodowania!!

Bibliografia

  1. https://essentialdeveloper.com
  2. https://developer.android.com/training/dependency-injection