์์กด์ฑ(Dependency)
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ์์กด์ฑ(Dependency)์ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด ์ฌ์ด์ ์์กด ๊ด๊ณ๊ฐ ์๋ค๋ ๊ฒ์ ๋งํฉ๋๋ค.
์ฆ, ์์กดํ๋ ๊ฐ์ฒด๊ฐ ์์ ๋๋ฉด, ๋ค๋ฅธ ๊ฐ์ฒด๋ ์ํฅ์ ๋ฐ๋๋ค๋ ๊ฒ์ ๋๋ค.
์์๋ก ์๋์ ์ฝ๋๋ฅผ ๋ด ์๋ค.
struct Coffee {
func drink() {
print("์ปคํผ๋ฅผ ๋ง์ ๋ค")
}
}
struct Programmer {
private let coffee = Coffee()
func startProgramming() {
self.coffee.drink()
}
}
Programmer๊ฐ์ฒด๋ Coffee๊ฐ์ฒด๋ฅผ ์ธ์คํด์ค๋ก ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก,
Programmer๊ฐ์ฒด์ startProgramming()์ด ํธ์ถ๋๊ธฐ ์ํด์๋ Coffee ๊ตฌ์กฐ์ฒด๊ฐ ํ์ํฉ๋๋ค.
์ด ๋ Programmer๊ฐ์ฒด๋ Coffee๊ฐ์ฒด์ ์์กด์ฑ์ ๊ฐ์ง๋ค ๋ผ๊ณ ํฉ๋๋ค.
๋ง์ฝ Coffee ๊ฐ์ฒด์ ์ค์ํ ์์ ์ด๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค๋ฉด? Programmer๊ฐ์ฒด๋ ์ํฅ์ ๋ฐ์ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด Coffee์ drink()๋ผ๋ ๋ฉ์๋์ ๊ฐ์ด ๋ฐ๋๊ฑฐ๋ ๋ฉ์๋ ์์ฒด๊ฐ ์์ด์ง๋ค๋ฉด
Programmer์ startProgramming() ๋ฉ์๋์ ์์ ๋ ํ์ํ๊ฒ ์ฃ ..
์ด๋ ๊ฒ ์์กด์ฑ์ ๊ฐ์ง๋ ์ฝ๋๊ฐ ๋ง์์ง๋ค๋ฉด, ์ฌํ์ฉ์ฑ์ด ๋จ์ด์ง๊ณ ๋งค๋ฒ ์์กด์ฑ์ ๊ฐ์ง๋ ๊ฐ์ฒด๋ค์ ํจ๊ป ์์ ํด ์ฃผ์ด์ผ ํ๋ค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋์จ ๊ฐ๋
์ด ๋ฐ๋ก Dependency Injection, ์์กด์ฑ ์ฃผ์
์
๋๋ค.
DI(์์กด์ฑ ์ฃผ์ )๋ฅผ ํด์ผ ํ๋ ์ด์
DI๋ก ํ๋ก๊ทธ๋จ์ ์ค๊ณ ํ์ ๋, ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค.
- Unit Test๊ฐ ์ฉ์ดํด์ง๋ค.
- ์ฝ๋์ ์ฌํ์ฉ์ฑ์ ๋์ฌ์ค๋ค.
- ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ(์ข ์์ฑ)์ ์ค์ด๊ฑฐ๋ ์์จ ์ ์๋ค.
- ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋์ด ๋ฎ์ถ๋ฉด์ ์ ์ฐํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
DI(Dependency Injection) - ์์กด์ฑ ์ฃผ์
์ฃผ์ (Injection) ์ ์ธ๋ถ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฃ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
struct Coffee {
var name: String
func drink() {
print("\(name)๋ฅผ ๋ง์ ๋ค")
}
}
struct Programmer {
private let coffee: Coffee
init(coffee: Coffee) {
self.coffee = coffee
}
func startProgramming() {
self.coffee.drink()
}
}
let americano = Coffee(name: "์๋ฉ๋ฆฌ์นด๋
ธ")
let programmer = Programmer(coffee: americano)
programmer.startProgramming()
์์ ์ฝ๋๋ Coffee๊ฐ์ฒด๋ฅผ ์ธ๋ถ์์ ์์ฑํ๊ณ Programmer ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ๋ฃ์ด์ฃผ๊ณ ์์ต๋๋ค.
์ด๋ ๊ฒ ์ธ๋ถ์์ ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ์์ฑ์ ๋ฑ์ ํ์ฉํด์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ ์ฃผ์
(injection)์ด๋ผ๊ณ ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ, ์ฃผ์
๋ง์ผ๋ก ์์กด์ฑ์ด ์ค์ด๋ค์๋ค๊ณ ํ ์ ์์๊น์?
๋ง์ฝ Coffee ๊ฐ์ฒด์ drink() ๋ฉ์๋๊ฐ ๋ฐ๋๋ค๋ฉด? Programmer์ startProgramming() ๋ฉ์๋ ๋ํ ์ํฅ์ ๋ฐ์ ๊ฒ์
๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ์์ ์์กด์ฑ์ ์ฃผ์
ํ๋ ๊ฒ ๋ง์ผ๋ก๋ ์์ง Programmer๊ฐ์ฒด์ Coffee ๊ฐ์ฒด์ ๋ํ ์์กด์ฑ์ ์ค์๋ค๊ณ ํ ์ ์์ต๋๋ค.
Swift์์๋ ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น(DIP: Dependency Injection Principal) ์ด ์ค์ํ ๊ฐ๋
์
๋๋ค.
์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น์ผ๋ก ์์กด ๊ด๊ณ๋ฅผ ๋ถ๋ฆฌ์์ผ ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ต๋๋ค.
DIP(Dependency Inversion Principle) - ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น
DIP, ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ค๊ณ์ ๋ค์ฏ๊ฐ์ง ๊ธฐ๋ณธ ์์น(SOLID)์ค ํ๋์
๋๋ค. (SOLID์ D)
์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น์ ์์ ๊ณ์ธต(์ ์ฑ
๊ฒฐ์ )์ด ํ์ ๊ณ์ธต(์ธ๋ถ ์ฌํญ)์ ์์กดํ๋ ์ ํต์ ์ธ ์์กด๊ด๊ณ๋ฅผ ๋ฐ์ ์ํด์ผ๋ก์จ
์์ ๊ณ์ธต์ด ํ์ ๊ณ์ธต์ ๊ตฌํ์ผ๋ก๋ถํฐ ๋ ๋ฆฝ๋๊ฒ ํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๋งํฉ๋๋ค.
์ด ๋ฒ์น์ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์์ต๋๋ค.
์ถ์ํ ๋ ๊ฒ(์์ ๋ชจ๋)์ ๊ตฌ์ฒด์ ์ธ ๊ฒ(ํ์ ๋ชจ๋)์ ์์กดํ๋ฉด ์๋๊ณ ๊ตฌ์ฒด์ ์ธ ๊ฒ(ํ์ ๋ชจ๋)์ด ์ถ์ํ๋ ๊ฒ(์์ ๋ชจ๋)์ ์์กด ํด์ผํ๋ค.
์ฆ, ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด๋ ์ถ์ํ๋ ๊ฐ์ฒด์ ์์กด ํด์ผ ํ๋ค๋ ๊ฒ์ด DIP์ ํต์ฌ์
๋๋ค.
Swift์์๋ Protocol์ ์ด์ฉํด ์ถ์์ ์ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค.
Protocol์ ํ์ฉํด ์์กด์ฑ ์ฃผ์
์ ๊ตฌํํด๋ด
์๋ค.
์์ ์์์ฝ๋๋ค์ Programmer ๊ฐ์ฒด๊ฐ Coffee ๊ฐ์ฒด(Programmer → Coffee)์ ์์กดํ๋ ๊ตฌ์กฐ์๋ค๋ฉด,
์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น์์๋ ์ด๋ค ์ถ์ํ๋ ์ธํฐํ์ด์ค(Swift์์๋ ํ๋กํ ์ฝ)์ ๋ ๊ฐ์ฒด๊ฐ ๋ชจ๋ ์์กดํ๊ณ ์๋ ๊ตฌ์กฐ(Coffee → ํ๋กํ ์ฝ ← Programmer)๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
protocol Drink {
func drink()
}
struct Coffee: Drink {
func drink() {
print("์๋ฉ๋ฆฌ์นด๋
ธ๋ฅผ ๋ง์ญ๋๋ค.")
}
}
struct Programmer {
private let coffee: Coffee
init(coffee: Coffee) {
self.coffee = coffee
}
func startProgramming() {
self.coffee.drink()
}
}
let americano = Coffee()
let programmer = Programmer(coffee: americano)
programmer.startProgramming()
Drinkํ๋กํ ์ฝ์ ์ฑํํ Coffee๊ฐ์ฒด์ drink()๊ฐ ์๋ค๋ฉด Coffee๋ฅผ ์ ์ธํ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
Programmer์ ๋ํ ์ ์ด์ ์ฃผ์ฒด๊ฐ Coffee์ ์๋๊ฒ ์๋๋ผ ํ๋กํ ์ฝ์ ์๋ ๊ฒ์
๋๋ค.
์ฆ, ์์ ๊ฐ์ฒด๊ณผ ํ์ ๊ฐ์ฒด ๋ชจ๋ ํ๋กํ ์ฝ์ ์์กดํด์์ด ๋ ๊ฐ์ฒด ์๋ก์ ๋ํ ์์กด ๊ด๊ณ๋ฅผ ๋
๋ฆฝ์ํจ ์ํ์
๋๋ค.
์ด๋ ๊ฒ ๊ตฌํํ๋ค๋ฉด ๋ ๊ฐ์ฒด๋ ๊ฑฐ์ ๋
๋ฆฝ์ ์ธ ๊ฐ์ฒด๊ฐ ๋๊ธฐ ๋๋ฌธ์,
ํ๋์ ๊ฐ์ฒด๋ฅผ ์์ ํ๋ค๊ณ ํด์ ์๋ ๊ฐ์ฒด๋ฅผ ํจ๊ป ์์ ํด์ผํ๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
[์ฐธ๊ณ ์๋ฃ]