การฉีดพึ่งพา

Dec 29 2022
DI เป็นเทคนิคที่ใช้กันอย่างแพร่หลายในการเขียนโปรแกรมซอฟต์แวร์ แม้ว่า Google จะแนะนำ DI ให้กับผู้พัฒนา Android แต่ Android ก็มีไลบรารีเช่น Dagger, Hilt เพื่อจุดประสงค์นี้

DI เป็นเทคนิคที่ใช้กันอย่างแพร่หลายในการเขียนโปรแกรมซอฟต์แวร์ แม้ว่า Google จะแนะนำ DI ให้กับผู้พัฒนา Android แต่ Android ก็มีไลบรารีเช่น Dagger, Hilt เพื่อจุดประสงค์นี้ DI ให้ข้อดีดังต่อไปนี้:

  1. การใช้รหัสซ้ำ
  2. ความง่ายในการปรับโครงสร้างใหม่
  3. ความง่ายในการทดสอบ

การพึ่งพาการฉีดเป็นเทคนิคที่ช่วยให้สามารถแยกวัตถุออกจากวัตถุที่พึ่งพาได้ มาดูตัวอย่างการนำ DI ไปใช้ใน 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ถูกฉีดไปที่DataDownloadจากผู้แต่ง/แอสเซมเบลอ ร์ Client1และClient2. นอกจากนี้ยังแยกรหัส ตอนนี้เราสามารถทดสอบพวกมันโดยแยกจากกันโดยไม่ต้องพึ่งพาการพึ่งพาที่ไม่ต้องการ ข้อดีบางประการจากการปรับโครงสร้างโค้ดด้านบน

  1. ความสะดวกในการทดสอบ
  2. การพัฒนาคุณสมบัติใหม่ที่รวดเร็วยิ่งขึ้น
  3. ปรับปรุงเวลาในการรวบรวม Xcode (ฉันจะเขียนบล็อกแยกต่างหากในเรื่องนี้)
  4. ประหยัดเวลาและเงิน
  1. การฉีดคอนสตรัค (อธิบายไว้ด้านบน)
  2. การฉีดฟังก์ชั่น
  3. การฉีดทรัพย์สิน

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

การฉีดคุณสมบัติ: HTTPClient จะถูกส่งผ่านเป็นการฉีดคุณสมบัติไปยัง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()
    }
}

หวังว่าจะช่วยได้! หากคุณชอบบทความและต้องการอ่านบทความที่น่าทึ่งเพิ่มเติม โปรดติดตามฉันที่นี่และแสดงการสนับสนุนของคุณเนื่องจากเป็นแรงกระตุ้นให้ฉันเขียนมากขึ้น

โปรดแบ่งปันความคิดเห็นของคุณเพื่อปรับปรุงเนื้อหาและเกี่ยวกับหัวข้อถัดไปที่คุณต้องการสำรวจ

ขอขอบคุณทุกท่านที่อ่าน มีความสุขในการเขียนโค้ด!!

อ้างอิง

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