Tiêm phụ thuộc

Dec 29 2022
DI là một kỹ thuật được sử dụng rộng rãi trong lập trình phần mềm. Ngay cả Google cũng khuyến nghị DI cho các nhà phát triển Android, Android có các thư viện như Dagger, Hilt cho mục đích này.

DI là một kỹ thuật được sử dụng rộng rãi trong lập trình phần mềm. Ngay cả Google cũng khuyến nghị DI cho các nhà phát triển Android, Android có các thư viện như Dagger, Hilt cho mục đích này. DI cung cấp các ưu điểm sau:

  1. Khả năng sử dụng lại mã
  2. Dễ tái cấu trúc
  3. Dễ kiểm tra

Dependency injection là một kỹ thuật cho phép các đối tượng được tách ra khỏi các đối tượng mà chúng phụ thuộc vào. Hãy lấy một ví dụ về cách triển khai DI trong 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")!)
    }
}

RemoteClientđược đưa vào DataDownloadtừ trình soạn thảo/trình biên dịch chương trình Client1Client2. Nó cũng tách mã. Bây giờ chúng tôi có thể kiểm tra chúng một cách riêng biệt mà không đáp ứng sự phụ thuộc không mong muốn. Một số ưu điểm từ việc tái cấu trúc mã ở trên

  1. Dễ dàng trong thử nghiệm.
  2. Phát triển nhanh hơn các tính năng mới.
  3. Cải thiện thời gian biên dịch Xcode (Tôi sẽ viết một blog riêng về vấn đề này).
  4. Tiết kiệm thời gian và tiền bạc.
  1. Constructor injection (đã giải thích ở trên)
  2. chức năng tiêm
  3. tiêm tài sản

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")!)
    }
}

Chèn thuộc tính : HTTPClient được chuyển dưới dạng Chèn thuộc tính vào 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()
    }
}

Hy vọng nó giúp! Nếu bạn thích bài viết này và muốn đọc thêm những bài viết tuyệt vời khác, thì hãy theo dõi tôi tại đây và thể hiện sự ủng hộ của bạn vì nó là động lực để tôi viết nhiều hơn.

Vui lòng chia sẻ phản hồi của bạn để cải thiện nội dung và về chủ đề tiếp theo mà bạn muốn khám phá.

Cảm ơn tất cả các bạn đã đọc, chúc mừng mã hóa!!

Người giới thiệu

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