๐ŸŽ iOS/Swift

Dependency Injection (์˜์กด์„ฑ ์ฃผ์ž…)

JerryiOS 2023. 5. 4. 13:58

Dependency(์˜์กด์„ฑ)

๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ Dependency, ์˜์กด์„ฑ์€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด ์‚ฌ์ด์— ์˜์กด ๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ฆ‰, ์˜์กดํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์ˆ˜์ •๋˜๋ฉด, ๋‹ค๋ฅธ ๊ฐ์ฒด๋„ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

import UIKit

struct Eat {
    func coffee() {
        print("์•„๋ฉ”๋ฆฌ์นด๋…ธ")
    }

    func meal() {
        print("ํ”ผ์ž")
    }
}

struct Person {
    var todayEat: Eat
    
    func coffee() {
        todayEat.coffee()
    }
    
    func meal() {
        todayEat.meal()
    }
}

Person๊ฐ์ฒด๋Š” Eat๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šค๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ, Eat๊ฐ์ฒด์— ์˜์กด์„ฑ์ด ์ƒ๊ธด๋‹ค.

์ฆ‰, Person๊ฐ์ฒด๋Š” Eat๊ฐ์ฒด์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค.

๋งŒ์•ฝ ์ด๋•Œ, Eat๊ฐ์ฒด์— ์ค‘์š”ํ•œ ์ˆ˜์ •์ด๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, Person๊ฐ์ฒด๋„ ์˜ํ–ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

์˜์กด์„ฑ์„ ๊ฐ€์ง€๋Š” ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง„๋‹ค๋ฉด, ์žฌํ™œ์šฉ์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ๋งค๋ฒˆ ์˜์กด์„ฑ์„ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด๋“ค์„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

์ด๋Ÿฌํ•œ ์˜์กด์„ฑ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๊ฐœ๋…์ด ๋ฐ”๋กœ Dependency Injection, ์˜์กด์„ฑ ์ฃผ์ž…์ด๋‹ค.

 

Injection(์ฃผ์ž…)

Injection, ์ฃผ์ž…์€ ์™ธ๋ถ€์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋„ฃ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.
class Eat: Menu {
    var coffee: String
    var meal: String
    
    init(coffee: String, meal: String) {
        self.coffee = coffee
        self.meal = meal
    }
    
    func printCoffee() {
        print("์•„๋ฉ”๋ฆฌ์นด๋…ธ")
    }
    
    func printMeal() {
        print("ํ”ผ์ž")
    }
}

let menu = Eat(coffee: "์•„๋ฉ”๋ฆฌ์นด๋…ธ", meal: "ํ”ผ์ž")

์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ƒ์„ฑ์ž๋ฅผ ํ™œ์šฉํ•ด์„œ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Dependency Injection

๋‚ด๋ถ€์—์„œ ๋งŒ๋“  ๊ฐ์ฒด๋ฅผ ์™ธ๋ถ€์— ๋„ฃ์–ด์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ

์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•˜๋Š” ์ด์œ ๋Š” ๋ญ˜๊นŒ?

  • Unit Test๊ฐ€ ์šฉ์ดํ•ด์ง„๋‹ค.
  • ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ธ๋‹ค.
  • ๊ฐ์ฒด ๊ฐ„ ์˜์กด์„ฑ์„ ์ค„์ด๊ฑฐ๋‚˜ ์—†์•จ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋ฉด์„œ ์œ ์—ฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Denpendency Inversion Principle (์˜์กด์„ฑ ์—ญ์ „ ์›์น™)

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์„ค๊ณ„์˜ SOLID ์›์น™ ์ค‘ ํ•˜๋‚˜๋กœ,

๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์„ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์˜์กดํ•ด์„œ๋Š” ์•ˆ๋˜๊ณ , ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์˜์กดํ•ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™

์„ ๋งํ•œ๋‹ค.

Swift์—์„œ ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ Protocol์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

์ด Protocol์„ ์ด์šฉํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•œ๋‹ค.

 

protocol Menu {
    func printCoffee()
    func printMeal()
}
class Eat: Menu {
    var coffee: String
    var meal: String
    
    init(coffee: String, meal: String) {
        self.coffee = coffee
        self.meal = meal
    }
    
    func printCoffee() {
        print("์•„๋ฉ”๋ฆฌ์นด๋…ธ")
    }
    
    func printMeal() {
        print("ํ”ผ์ž")
    }
}
struct Person {
    var todayEat: Menu
    
    func printCoffee() {
        todayEat.printCoffee()
    }
    
    func printMeal() {
        todayEat.printMeal()
    }
    
    mutating func changeMenu(menu: Menu) {
        self.todayEat = menu
    }
}

์ด๋ ‡๊ฒŒ Protocol์„ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋ฉด

Eat๊ฐ์ฒด์™€ Person๊ฐ์ฒด๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์ธ ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค.

Eat๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ Person์„ ์ˆ˜์ •ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์ƒ๋Œ€ ๊ฐ์ฒด๋ฅผ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฐ˜์‘ํ˜•