의존성 주입(Dependency Injection)

: 객체가 직접 의존성을 생성하지 않고, 외부에서 주입 받도록 하는 설계 패턴이다. 즉 클래스 내부에서 필요한 객체를 직접 만들지 않고 외부에서 넣어주는 것이다.

사용하는 이유

  1. 코드의 결합도를 낮춘다. (Loose coupling)
  2. 테스트하기 쉬워진다.
  3. 재사용성과 유지보수성이 높아진다.

방식 3가지

  1. 생성자 주입 (Constructor Injection) + 프로토콜 사용

    protocol DataService {
        func fetchData() -> String
    }
    
    class APIService: DataService {
        func fetchData() -> String {
            return "실제 API 데이터"
        }
    }
    
    class ViewModel {
        let dataService: DataService  // 의존성
    
        // 생성자를 통해 의존성을 주입받음
        init(dataService: DataService) {
            self.dataService = dataService
        }
    
        func getData() {
            print(dataService.fetchData())
        }
    }
    
    // 주입 예시
    let apiService = APIService()
    let viewModel = ViewModel(dataService: apiService) // 의존성 주입
    viewModel.getData()  // "실제 API 데이터" 출력
    
  2. 프로퍼티 주입 (Property Injection)

    class ViewModel {
        var dataService: DataService? // 나중에 주입받을 수 있도록 옵셔널로 선언
    
        func getData() {
            print(dataService?.fetchData() ?? "데이터 없음")
        }
    }
    
    // 주입 예시
    let apiService = APIService()
    let viewModel = ViewModel()
    viewModel.dataService = apiService  // 의존성 주입
    viewModel.getData()  // "실제 API 데이터" 출력
    

    ❌ 객체가 완전히 초기화되지 않을 위험이 있다. (nil 체크 필요)

  3. 메서드 주입 (Method Injection)

    class ViewModel {
        func getData(dataService: DataService) {
            print(dataService.fetchData())
        }
    }
    
    // 주입 예시
    let apiService = APIService()
    let viewModel = ViewModel()
    viewModel.getData(dataService: apiService)  // "실제 API 데이터" 출력
    

    ❌ 의존성이 명확하게 드러나지 않는다. (메서드를 사용할 때마다 주입해야 함)

MVVM(Model-View-View Model)