์์กด์ฑ ์ฃผ์ ์ ๊ณ ๋ฏผํ๊ฒ ๋ ๊ณ๊ธฐ
ํ๋ ์์ํฌ ๋ด์์ ๋ค๋ฅธ add-on ํ๋ ์์ํฌ api๋ฅผ ์ฌ์ฉํ ๋,
dynamic ํ๋ ์์ํฌ๋ ํ๋ก์ ํธ ๋ด embed ํ ๊ฒฝ์ฐ, ํด๋น api๊ฐ ์ ์ ํธ์ถ๋์ง๋ง,
embed ํ์ง ์๊ณ ํธ์ถํ๋ ๊ฒฝ์ฐ, ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ฐ, ์ด ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ๊ตฌํ์ด ํ์ํ๋ค.
์์กด์ฑ ์ฃผ์ (DI, Dependency Injection) ์ด๋?
๋จผ์ , ๋ ๋จ์ด๋ฅผ ๋ฏ์ด์ ๋ณด๋ฉด,
์์กด์ฑ(Dependency) ์ด๋ ? ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด ์ฌ์ด์ ์์กด ๊ด๊ณ๊ฐ ์๋ค๋ ๊ฒ์ ๋งํ๋ค.
์ฝ๋๋ก ์ดํดํด๋ณด์.
์ฆ, ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ํด๋์ค A๊ฐ B๋ฅผ ์ง์ ์์ฑํ๊ณ ์ฌ์ฉํ๋ค๋ฉด, 'A ๊ฐ์ฒด๊ฐ B ๊ฐ์ฒด๋ฅผ ์์กดํ๋ค' ๋ผ๊ณ ํ๋ค.
๋ฌด์จ ๋ง์ด๋
์ ์ฝ๋์ B ํด๋์ค name ๋ณ์๋ฅผ name2๋ก ๋ณ๊ฒฝํด๋ณด๋ฉด,
๋ฐ๋ก A ํด๋์ค์์ ์๋ฌ๊ฐ ๋ฐ์!!!!
๋ฐ๋ผ์ B ํด๋์ค์์ ๋ณ๊ฒฝ์ฌํญ์ด ์๊ธฐ๋ฉด, A์์๋ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ์ํด์ฃผ์ด์ผ ํ๋ค!
์ฆ, ์์กดํ๋ ๊ฐ์ฒด๊ฐ ์์ ๋๋ฉด, ๋ค๋ฅธ ๊ฐ์ฒด๋ ์ํฅ์ ๋ฐ๋๋ค๋ ๊ฒ์ด๋ค.
์์ ๊ฐ์ด A๊ฐ B๋ฅผ ๋ฉค๋ฒ๋ณ์ ๋ฐ ๋ก์ปฌ๋ณ์๋ก ๊ฐ์ง๊ณ ์๊ฑฐ๋ B์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ, B์ ๊ด๋ จ๋ ์ด๋ ํ ์ฐ๊ด๋ ์ผ์ ํ๋ ๊ฒฝ์ฐ ์์กดํ๋ค๋ผ๊ณ ํํํ ์ ์๋ค.
์ ์ฝ๋์์ A ๊ฐ์ฒด๋ B ๊ฐ์ฒด์ ์์กดํ๋ค๋ ๊ฒ์ด๋ค.
*์์กด ๊ด๊ณ์ ๋ฌธ์ ์ :
- A ๊ฐ์ฒด๋ B ๊ฐ์ฒด๋ฅผ ์์กดํ๊ณ ์์ผ๋ฏ๋ก, A๊ฐ์ฒด๊ฐ ์๋ฌด๊ฒ๋ ๋ณํ์ง ์์์์๋ ์์์น ๋ชปํ ๋์์ ํ๊ฑฐ๋ ์ปดํ์ผ์ด ์๋๋ ์ผ ๋ฐ์
- A์ ์ฌ์ฌ์ฉ์ฑ์ด ๋ฎ์์ง๋ค. ๋ง์ฝ A๋ฅผ ๋ค๋ฅธ ๋ชจ๋ ๋๋ ๋ค๋ฅธ ํด๋์ค์ ์ฌ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ, B๋ ๋์ด์์ผ ํ๋ ์ํฉ์ด ๋ฐ์
๊ทธ๋ ๋ด, ์ฃผ์ (Injection)์ด๋?
์ธ๋ถ์์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋, ๊ฐ์ ์ฃผ์ ํ๋ค๊ณ ํ๋ค.
์ฐ๋ฆฌ๊ฐ ๋ ์ฐ๋ ์์ฑ์(init)๊ฐ ๋ฐ๋ก ์ด ๊ฐ๋ ์ด๋ค.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let person = Person(name: "์ผ์ฐ")
์ ์ฝ๋์ ๊ฐ์ด ์ธ๋ถ์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋, ์์ฑ์๋ฅผ ํตํด ๊ฐ์ ๋ฃ์ด์ฃผ๋ ๊ฒ!
๊ทธ๋ผ, ๋ ๋จ์ด๋ฅผ ํฉ์น ์์กด์ฑ ์ฃผ์ (Dependency Injection, DI)์ด๋?
๊ธฐ์กด์ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ํ ์ ์๋๋ก ๋ฐ๊ฟ๋ ๊ฒ์ด๋ค. ์ฆ, ๋ ํด๋์ค๊ฐ ์์กด์ ์ด์ง ์์ ๊ด๊ณ๋ก ๋ง๋ค์ด ์ฃผ๋ ๊ฒ์ด๋ค.
์ธ๋ถ์์ ์ด๊ธฐํํด์ ํด๋์ค ์์ ํ ๋นํด์ฃผ๋ฏ๋ก ์ ์ฐํ ๊ตฌ์กฐ๊ฐ ๋๋ค.
์ด๋ป๊ฒ ์ ์ฉํ์ง ?
์์กด์ฑ ์ฃผ์ ์ ์ฉํ๊ธฐ - ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น(DIP, Dependency Inversion Principle)
์ฐ๋ฆฌ์ ๋ชฉํ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด A์ Bํด๋์ค์ ์์กด์ฑ์ ๋๊ณ , ์ธ๋ถ์์ B๋ฅผ ๋ง๋ ํ ๋ง๋ ๊ฒ์ ๊ฐ์ ธ์์ A๊ฐ ์ฌ์ฉํ๋๋ก ๋ฐ๊พธ์ด ์ฃผ์ด์ผ ํ๋ค.
์ฆ, A๊ฐ์ฒด๊ฐ B๊ฐ์ฒด๊ฐ ์๋ ์ธ๋ถ(๋งค๊ฐ์ฒด)์ ์์กดํ๋๋ก ํ๋ ๊ฒ์ด๋ค.
์ด ๋, ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ค๊ณ์ ์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น(DIP)์ ๋ฐ๋ผ,
๊ฐ์ฒด๋ค ์ค๊ฐ์ ์ ์ด๊ถ์ ๊ฐ์ง๋ ์ด ๋งค๊ฐ์ฒด๋ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ด ์๋ ์ถ์ํ๋ ๊ฒ์ด ๋๋ค.
*๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋จ (OOP)์ 5๋ ์์น(SOLID) ์ค ํ๋์ธ ์์กด๊ด๊ณ ์ญ์ ์์น(DIP: Dependency Inversion Principle) ์์กด ๊ด๊ณ ๋ถ๋ฆฌ : ์ถ์ํ๋ ๊ฒ์ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ ์์กดํ๋ฉด ์๋๊ณ , ๊ตฌ์ฒด์ ์ธ ๊ฒ์ด ์ถ์ํ๋ ๊ฒ์ ์์กดํด์ผ ํ๋ค.
์ฆ, ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด๋ ์ถ์ํ๋ ๊ฐ์ฒด(ํ๋กํ ์ฝ)์ ์์กดํด์ผ ํ๋ค.
์ด ๋ฒ์น์ ๊ธฐ์กด ์์กด๊ด๊ณ๋ฅผ ์ญ์ ์ํด์ผ๋ก์จ Aํด๋์ค์ Bํด๋์ค๊ฐ ๋ ๋ฆฝ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ๋๋ค.
[๊ธฐ์กด ๊ตฌ์กฐ]
[์์กด ๊ด๊ณ ์ญ์ ๋ฒ์น ๊ตฌ์กฐ]
์ด๋ ๊ฒ ์์กด ๋ฐฉํฅ์ด ์ญ์ ๋์ด ์ ์ด๊ฐ ๋ฐ์ ๋๋ ์ํฉ์ ์ ์ด์ ๋ฐ์ (IoC, Inversion of Control)์ด๋ผ๊ณ ํํํ๋ค.
์ด ๋, ์ด ์ถ์ํ ๋ ๊ฒ(๋งค๊ฐ์ฒด)์ด Swift์์๋ Protocol์ด ์๋ค.
์ฐ๋ฆฌ๋ ์ด Protocol์ ํ์ฉํด์ ์์กด์ฑ ์ฃผ์ ์ ๊ตฌํํด๋ณด์.
์ฐ์ Protocol์ ํ์ฉํด์ ์ถ์์ ์ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
protocol DIInterface {
var name: String{ get set }
}
Bํด๋์ค๊ฐ ์์ฑํ DIInterface Protocol์ ์ฑํํ์ฌ ์ ์ํ ๋ณ์๋ ํ ๋นํด์ค๋ค.
class B: DIInterface {
var name: String = "B๋ณ์"
}
DI๋ฅผ ์ ์ฉํ๊ธฐ ์ํด Aํด๋์ค์ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ๋๋ก ๊ตฌํํด๋ณด์.
Aํด๋์ค ์์ฑ ๋ฐ ์ฌ์ฉ ์ ์ํ๋ DIInterface ์ธ์คํด์ค๋ฅผ ์ฃผ์ ํ ์ ์๋ค.
class A{
// ํ๋กํ ์ฝ๋ก ํ์
์ผ๋ก ๋ณ์ ์ ์ธ
var b: DIInterface
//ํ๋กํ ์ฝ์ ์ ์ธ๋ ๋ชจ๋ ํ์
๋ค์ ์ ์ธ ๊ฐ๋ฅํ๋ค.
init(b: DIInterface) {
self.b = b
}
func printName() {
print(b.name)
}
}
์ด๋ ๊ฒ ๊ตฌํํ๋ค๋ฉด, A๊ฐ์ฒด์ B๊ฐ์ฒด๋ ๋ ๋ฆฝ์ ์ธ ๊ฐ์ฒด๊ฐ ๋๋ค.
์ฆ, ๊ธฐ์กด์ฒ๋ผ Bํด๋์ค์ name ๋ณ์๊ฐ ์ด๋ฆ์ ๋ฐ๊พธ๊ฑฐ๋ ์์ด๋ A๋ฅผ ์์ ํด์ผ๋๋ ์ผ์ ์๋ค.
์ฆ, ๊ธฐ์กด์๋ ์์กด์ฑ์ ์ง์ ๋ชจ๋ ์ ์ดํ๋ค๋ฉด ์ ์ด๊ถ์ด ์ญ์ ๋์ด Protocol์ ์ ์ด๊ถ์ด ์๋ค๋ ๊ฒ์ด๋ค.
๋ํ, ๋ชจ๋์ ์ถ๊ฐ ๊ฐ๋ฅํ๋ค.
A ํด๋์ค์ ์๋ก์ด b๊ฐ ํ์ํ๋ค๋ฉด DIInterface Protocol์ ์ฑํํ ์๋ก์ด C ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด์.
DIInterface Protocol์ ์ค์ํ๋ ์ด๋ค ํ์ ์ด๋ผ๋ ์ ์ฅํ ์ ์๋๋ก ํ๋ค.
์ด์ , ์ฌ์ฉ์๊ฐ ์ง์ ์์ฑํ์ง ์๊ณ ํ์ํ ๋ DIInterface๊ฐ ์์กด์ฑ ์๋ ๋ชจ๋๋ค์ ์ฃผ์ ํด ์ฃผ๋ ๊ฒ์ด๋ค.
protocol DIInterface {
var name: String{ get set }
}
class B: DIInterface {
var name: String = "B๋ณ์"
}
class C: DIInterface {
var name: String = "C๋ณ์"
}
class A{
var b: DIInterface
init(b: DIInterface) {
self.b = b
}
func printName() {
print(b.name)
}
}
let moduledB = B()
let moduledC = C()
let devlopedA = A(b: moduledB)
protocol ํ์ ์ผ๋ก ๋จ๋๊น ํ๋กํ ์ฝ์ ์์๋ฐ์ ๋ชจ๋ ์ ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
์ฆ, ์ฃผ์ ์ ํ๋ protocol ํ์ ์ผ๋ก ์ฃผ์ ์ ํด์ ์ฌ๋ฌ๊ฐ์ง ์ฝ๋๋ก ํ์ฅํด์ ๋ง๋ค ์ ์๋ค๋ ๊ฒ!!!
์์ ์์กด์ฑ ๋๋ Aํด๋์ค์ Bํด๋์ค์ ๊ตฌ์กฐ๊ฐ ์์กด์ฑ ์ฃผ์ ์ผ๋ก ์ธํด ์๋์ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ๋๋ค.
DIInterface(Protocol)์๊ฒ ๋ชจ๋ ๊ด๊ณ์ค์ ์ ๊ดํ ์ฑ ์์ ์์์ ํ๊ฒ ๋์๋ค.
์์กด์ฑ ์ฃผ์ ์ ์ฅ๋จ์
โ๏ธ ์ฅ์
- ๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ๋(Coupling)์ ๋ฎ์ถฐ ์์กด์ฑ ๊ฐ์
- ๋ณ๊ฒฝ์ ๋ฏผ๊ฐํ์ง ์์ ๊ธฐ์กด ๊ธฐ๋ฅ ๋ฆฌํฉํ ๋ง ์์ ๋ฐ ์ ๊ธฐ๋ฅ ๊ฐ๋ฐ ์ฉ์ด
- ๋ชจ๋๋ณ ๋ ๋ฆฝ์ ์ธ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ
- ์ ์ง๋ณด์ ์ฉ์ด
- ๋น๋์๊ฐ ๋จ์ถ
- ๊ฐ์ฒด๊ฐ ์์กด์ฑ์ ๋ฐ๋ ์์ ์ด ์ปดํ์ผํ์์ด ์๋ ๋ฐํ์์ผ๋ก ๋ฆ์ถฐ์ง๋ค.
- staticํ class Dependency๊ฐ ๋ฐํ์์ dynamicํ object Dependency๋ก ๋ณ๊ฒฝ ๋์ด ๋น๋ ์๊ฐ ๋จ์ถ
- ํ
์คํธ ์ฉ์ด์ฑ
- ์ฃผ์ ํ ์์กด ๊ฐ์ฒด๋ฅผ Mock ๊ฐ์ฒด๋ก ๊ตฌํํ ํ ์ฃผ์
โ๏ธ ๋จ์
- ์ฝ๋๊ฐ ๋ณต์กํด์ ธ ์ดํดํ๊ธฐ ์ด๋ ค์์ง
- ์์กด์ฑ ์ฃผ์ ์ ์ํ ์ ํ ์์ ์ด ํ์
- ํธ์ถ๋ค์ด protocol๋ก ์ฐ๊ฒฐ๋์ด ์์ด์ ํธ์ถ์ ๋ฐ๋ผ๊ฐ๊ธฐ๊ฐ ํ๋ค์ด์ง
- ๋๋ฒ๊น ์ด ์ด๋ ค์์ง
Interface Injection
๋ด๊ฐ ๊ณ ๋ฏผํ๋ค ์ฌ์ฉํ ๋ฐฉ๋ฒ์ผ๋ก Interface๋ฅผ ์ด์ฉํ์ฌ ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ์ถ์ํ ๊ฐ๋ ์์ swift์์๋ ํด๋์ค๋ฅผ ์ ์ํ๋ ์ถ์ํ ๋ฐฉ๋ฒ์ protocol์ด ์์
Interface๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๊ธด๋ฐํ๊ฒ ์ฐ๊ฒฐ๋์ด ์๋ ์์กด์ฑ์ด ์ฝํด์ ธ ๋ชจ๋๊ณผ ๋ชจ๋์ฌ์ด์ ๊ฒฐํฉ์ด ์ค์ด๋ ๋ค.