Dependency Injection이란
어떤 object에게 그것이 필요로 하는 것, 객체 즉 dependency를 주는 것(Give)
그 object가 다른 객체들(dependencies)을 직접 만들게 하는 게 아니라!
유의어들: initializer injection = constructor injection, property injection, method injection
(이들은 Dependency injection을 구현하는 방법들이라고 합니다.)
이해하기 쉬운 예제 코드
class ParentView {
let networkManager = NetworkManager()
let bag = Bag()
let childView: ChildView = ChildView()
}
class ChildView {
let networkManager = NetworkManager()
let bag = Bag()
}
without DI
class ParentView {
let networkManager = NetworkManager()
let bag = Bag()
let childView: ChildView = ChildView(networkManager: networkManager, bag: bag)
}
class ChildView {
let networkManager:networkManager
let bag:Bag
init(networkManager: NetworkManager, bag: Bag) {
self.networkManager = networkManager
self.bag = bag
}
}
with DI
이렇게 ChildView가 NetworkManager, Bag을 직접 생성하도록 하는 것이 아니라,
ParentView에서 ChildView의 생성자를 통해 넣어주는 것을 Initializer Injection, 즉 Dependency Injection 이라고 한다.
장점
언뜻보면 ChildView의 코드가 더 길어진 것 처럼 보여서 왜 DI를 해야하는지 장점은 무엇인지 살펴보면
- 간단해진 데이터 흐름 (Linear data flow)
- DI를 사용한 상황에선 ParentView가 ChildView를 생성할 때 NetworkManager와 Bag을 같이 보내주는 하나의 데이터 흐름만 가진다. (ParentView — 💼 🛜 —> ChildView)
- 그치만 DI를 쓰지 않는다면 ParentView에서 ChildView를 생성하고, 그 다음에 ChildView에서 NetworkManager와 Bag을 생성하는 식으로 데이터 흐름이 복잡해진다. (ParentView → ChildView → 💼 & 🛜 )
- 만약에 NetworkManager가 앱 전체에서 공통으로 사용되는 싱글톤 객체라면, 더욱 DI가 없다면 문제가 될 것 같다.
- 관심의 독립, 관심 분리 (Separation of concerns)
- DI를 사용해서 ChildView가 NetMan과 Bag을 주입받게 되면, ChildView는 내부적으로 NetMan과 Bag을 생성하지 않아도 되고, 즉 그것의 생성에는 신경쓰지 않아도 되고, 본인의 역할에 충실할 수 있게 됨.
- 쉬워진 테스팅 (Easier Testing)(이건 케바케일 것 같긴한데 어쨌든)
- DI를 사용하면, ChildView를 테스트하기가 쉬워진다. 테스트할 때 ChildView의 기능과는 관련없는 NetworkManager와 Bag에 대해서는 신경쓰지 않고 그들의 mock을 만들어서 넣어주기만 하면 된다.
dependency injection 다시 보니까 글로만은 헷갈리는 부분이 많았는데 이분 영상 이해하기 쉽게 설명해주신 것 같다!
https://www.youtube.com/watch?v=XTAziR-tY-A&t=6656s
+ Property Injection은 생성자를 통해 전달하지 않고, 의존성이 있는 객체를 옵셔널 프로퍼티로 선언해서 필요할 때 주입할 수 있도록 하는 방식 (런타임 에러 날 확률 있음)
+ Method Injection은 method의 매개변수로 전달하는 경우인데, 특정 메서드에서 한번만 사용되는 의존성 객체가 있을 경우 사용하기 좋다고 함. 다만 여러번 필요하면 그때마다 전달해줘야해서 번거로울 수 있음.
+ Swift에서는 Initializer Injection이 가장 선호된다고 함(GPT 피셜)
'iOS' 카테고리의 다른 글
[iOS] Delegate & Protocol (0) | 2025.03.26 |
---|---|
[iOS+@] Concurrency (동시성) (0) | 2025.03.25 |
[Swift] 순환참조와 strong, weak, unowned (0) | 2025.03.14 |
[iOS] Combine 기초 (추가 중) (0) | 2025.02.13 |
[SwiftUI] Environment value : dismiss (NavigationStack에서 뷰 닫기) (0) | 2024.12.26 |