의존성 주입(Dependency Injection)
- 특정 객체가 필요로하는 것들을 내부적으로 생성하게 두지 않고, 외부에서 제공해주는 것.
- 인스턴스 생성의 책임을 객체가 스스로 하도록 하지 않고 initializer, peroperty, method parameter의 형태로 “넘겨주는 것”
🤨 왜?
- 의존성이 높을 경우, 아래와 같은 문제가 있다.
- 클래스간의 결합도가 높아진다.
- 자연스럽게 테스트 성도 낮아진다.
- 코드 재사용성이 낮아진다.
- 의존성 주입을 해주면 아래와 같은 이점이 생긴다.
- 객체가 의존성을 받는 시점을 컴파일 타임이 아닌, 런타임으로 늦출 수 있다.
- 클래스가 생성이 된 후에도 프로퍼티 값등을 변경할 수 있다.
- 가장 쉬운 의존성 주입 예를 봐보자, 아래와 같이 ViewController 클래스가 있다고 가정해보자. 그리고 requestManager 변수를 세팅하는 방법이 두가지가 있다.
class ViewController:UIViewController {
var requestManager:RequestManager?
}
- 첫번째는 ViewController가 직접 변수를 생성하도록 하는 방법이 있다.
// ViewController 클래스 내부에서
class ViewController:UIViewController {
var requestManager:RequestManager?=RequestManager()
}
- 🌟 두번째는 의존성 주입(밖에서 생성하여 객체에게 주입)을 하는 방법이 있다.
class ViewController:UIViewController {
var requestManager:RequestManager?
}
let viewController=ViewController()
viewController.requestManager=RequestManager()
💥 의존 역전 법칙(Dependency Inversion Principle)
- 의존성 분리(객체와 객체 사이에 인터페이스를 끼워주어, 의존관계를 설정하는 것)를 하기위한 방법.
- 상위 계층은 하위 계층에 의존해서는 안된다, 두 계층은 모두 추상화에 의존해야된다.
- 즉 상위계층는 하위계층에 의존하지않고, 인터페이스에 의존을 한다.
Swift에서는 의존성 주입을 위한 인터페이스로 protocol을 사용한다.
- 즉, 아래의 예시에서는 상위 계층인 Amphibia(양서류)가 하위 계층인 Frog에 의존을 한다.
class Amphibia {
var example = Frog()
}
class Frog {
var name = "개구리"
}
- 이러한 문제점을 해결하기위하여 Animal이라는 protocol을 만들어 의존성을 역전시켜주는 것이다. (하위계층과 상위 계층 둘 다 인터페이스-Protocol에 의존을 하는 것)
protocol Animal {
var name: String { get set }
func move()
}
class Amphibia {
var example: Animal
init(example: Animal){
self.example = example
}
}
class Frog: Animal {
var name = "개구리"
func move() {
print("나는 움직일수 있어")
}
}
let frog = Frog()
// 객체를 주입한다!
let amphibia = Amphibia(example:frog)
📚 참고자료
iOS 의존성 주입(Dependency Injection)
(By. Mason Kim)
'iOS' 카테고리의 다른 글
[iOS] Singleton(싱글톤) (0) | 2023.02.04 |
---|---|
[iOS] 메모리 구조/ARC(Automatic Reference Count) (0) | 2023.02.04 |
[iOS] Delegate Pattern (0) | 2023.02.04 |
[iOS] Queue 구현하기 (0) | 2023.02.04 |
[iOS] Priority(Autolayout) (0) | 2023.02.03 |