Dependency Injection - ehrldyd15/Swift_Skills GitHub Wiki
Dependency Injection
์์กด์ฑ์ด๋(Dependency)?
์๋ก ๋ค๋ฅธ ๊ฐ์ฒด ์ฌ์ด์ ์์กด ๊ด๊ณ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ฆ, ์์กดํ๋ ๊ฐ์ฒด๊ฐ ์์ ๋๋ฉด, ๋ค๋ฅธ ๊ฐ์ฒด๋ ์ํฅ์ ๋ฐ์
import UIKit
struct Eat {
func coffee() {
print("์๋ฉ๋ฆฌ์นด๋
ธ")
}
func meal() {
print("ํผ์")
}
}
struct Person {
var todayEat: Eat // Eat์ ๋ํ ์์กด์ฑ์ด ์๊ธด๋ค.
func coffee() {
todayEat.coffee()
}
func meal() {
todayEat.meal()
}
}
Person๊ฐ์ฒด๋ Eat๊ฐ์ฒด๋ฅผ ์ธ์คํด์ค๋ก ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก, 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๊ฐ ์ฉ์ดํ๋ค.
- ์ฝ๋์ ์ฌํ์ฉ์ฑ์ ๋์ฌ์ค๋ค.
- ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ(์ข ์์ฑ)์ ์ค์ด๊ฑฐ๋ ์์จ ์ ์๋ค.
- ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ฉด์ ์ ์ฐํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
๋ด๋ถ์์ ๋ง๋ ๊ฐ์ฒด๋ฅผ ์ธ๋ถ์์ ๋ฃ์ด์ ์์กด์ฑ์ ์ฃผ์ ํ๊ธฐ ์ ์ '์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น'์ ์์๋ณด์
์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น(Dependency Inversion Principle)
DIP, ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ค๊ณ์ ๋ค์ฏ๊ฐ์ง ๊ธฐ๋ณธ ์์น(SOLID) ์ค ํ๋์ด๋ค.
์ถ์ํ ๋ ๊ฒ์ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ ์์กดํ๋ฉด ์๋๊ณ , ๊ตฌ์ฒด์ ์ธ ๊ฒ์ด ์ถ์ํ๋ ๊ฒ์ ์์กด ํด์ผํ๋ค.
์ฆ, ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด๋ ์ถ์ํ๋ ๊ฐ์ฒด์ ์์กด ํด์ผ ํ๋ค๋ ๊ฒ์ด ํต์ฌ์ด๋ค.
Swift์์ ์ถ์ํ๋ ๊ฐ์ฒด๋ Protocol์ด ์๋ค.
์ฐ๋ฆฌ๋ ์ด Protocol์ ํ์ฉํด์ ์์กด์ฑ ์ฃผ์ ์ ๊ตฌํํ๋ ค๊ณ ํ๋ค.
์ฐ์ Protocol์ ํ์ฉํด์ ์ถ์์ ์ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
Menu๋ผ๋ Protocol์ printCoffee()์ printMeal()ํจ์๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
protocol Menu {
func printCoffee()
func printMeal()
}
์ดํ Eatํด๋์ค๋ Menu Protocol์ ์ฑํํ ํ,
Protocol์ ์ ์ํ ํจ์๋ฅผ ์ค์ฒดํ ์์ผ์ค๋ค.
class Eat: Menu {
var coffee: String
var meal: String
init(coffee: String, meal: String) {
self.coffee = coffee
self.meal = meal
}
func printCoffee() {
print(coffee)
}
func printMeal() {
print(meal)
}
}
๊ธฐ์กด์ ๋ฐฉ์๊ณผ ๋ค๋ฅด๊ฒ todayEat๋ณ์๋ ์ถ์์ ์ธ ๊ฐ์ฒด์ธ Menuํ์ ์ ์์กดํ๊ฒ ๋๋ค.
์ฌ๊ธฐ์ changeMenuํจ์๋ฅผ ํ์ฉํด์ ์์กด์ฑ ์ฃผ์ ์ ์ํฌ ์ ์๋ค.
struct Person {
var todayEat: Menu
func printCoffee() {
todayEat.printCoffee()
}
func printMeal() {
todayEat.printMeal()
}
mutating func changeMenu(menu: Menu) {
self.todayEat = menu
}
}
์ด๋ ๊ฒ ๊ตฌํํ๋ค๋ฉด Eat๊ฐ์ฒด์ Person๊ฐ์ฒด๋ ๊ฑฐ์ ๋ ๋ฆฝ์ ์ธ ๊ฐ์ฒด๊ฐ ๋๋ค.
Eat ๊ฐ์ฒด๋ฅผ ์์ ํ๊ฑฐ๋ Person์ ์์ ํ๋ค๊ณ ํด์ ์๋ ๊ฐ์ฒด๋ฅผ ํจ๊ป ์์ ํด์ผ ํ๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
let menu = Eat(coffee: "์๋ฉ๋ฆฌ์นด๋
ธ", meal: "ํผ์")
let anotherMenu = Eat(coffee: "๋ผ๋ผ", meal: "ํ๋ฒ๊ฑฐ")
var suhshin = Person(todayEat: menu)
suhshin.printCoffee() // print ์๋ฉ๋ฆฌ์นด๋
ธ
suhshin.changeMenu(menu: anotherMenu)
suhshin.printCoffee() // print ๋ผ๋ผ
์๋ฃ์ถ์ฒ
https://80000coding.oopy.io/68ee8d89-5d05-449d-87e2-5fba84d604ca