의존성 주입 (DI: Dependency Injection)

한담곰·2026년 5월 13일

쏘의 Swift_Study

목록 보기
16/17

의존성이란

서로 다른 객체 사이에서 의존 관계가 있다는 것을 말한다. 즉, 의존하는 객체가 수정되면 다른 객체도 영향을 받는 것.

struct Eat {
	func coffee() { print("Coffee") }
    func meal() { print("Pizza") }
}

struct Person {
	var todayEat: Eat
    func coffee() { todayEat.coffee() }
    func meal() { todayEat.meal() }
}

-> Person 객체는 Eat 객체를 인스턴스로 사용하고 있으므로 Eat 객체에 의존성이 생긴다. 만약, 이때 Eat 객체에 중요한 수정이나 오류가 발생한다면 Person 객체도 영향을 받을 수 있다. 의존성을 가지는 코드가 많아진다면, 재활용성도 저하되고 매번 의존성을 가지는 객체들을 함께 수정해 주어야 함.

이러한 의존성 문제 해결을 위해 나온 개념이 의존성 주입(DI: Dependency Injeciton)이다.

주입(Injection)이란

외부에서 객체를 생성해서 넣는 것이다.

classs Eat: Menu {
	var coffee: String
    var meal: String
    
    init(coffee: String, meal: String) {
    	self.coffee = coffee 
        self.meal = meal
    }
    
    func printCoffee() { print("Coffee") }
    func printMeal() { print("Pizza") }
}

let menu = Eat(coffee: "Coffee", meal: "Pizza")

이렇게 생성자 (등등..) 를 활용하여 외부에서 주입이 가능!

DI

그렇다면... 의존성 주입을 왜 할까?
(1) 유닛 테스트가 용이해진다.
(2) 코드의 재활용성이 높아진다.
(3) 객체 간의 종속성(의존성)이 낮아진다.
(4) 객체 간의 결합도를 낮추면서 유연한 코드를 작성할 수 있다.

의존관계 역전 법칙 (DIP: Dependency Injection Principle)

  • 객체지향설계의 SOLIBD 중 하나로, 추상화 된 것은 구체적인 것에 의존하지 않고 구체적인 것이 추상화된 것에 의존한다는 것이다.
  • 구체적인 객체는 추상화된 객체의 의존해야 한다.
  • Swift에서 추상화된 객체는 Protocol이 있다.

Protocol을 활용한 의존성 주입 Code

protocol Menu {
	func printCoffee()
    func printMeal()
}

class Eat: Menu { // Menu 프로토콜 채택 후
	var coffee: String
    var meal: String
    
    init(coffee: String, meal: String) {
    	self.coffee = coffee
        self.meal = meal
    }
    
    func printCoffee() { print("커피") }
    func printMeal() { print("피자") } // Menu 프로토콜에서 정의한 함수를 실체화시킴
}

// 이제부터가 중요합니다...

struct Person {
	var todayEat: Menu // todayEat 변수는 추상적인 객체인 Menu 타입에 의존하게 됨.
    func printCoffee() { todayEat.printCoffee() }
    func printMeal() { todayEat.printMeal() }
    
    mutating func changeMenu(menu: Menu) {  // changeMenu 함수를 활용하여 의존성 주입 가능
    	self.todayEat = menu
    }
}

이렇게 구현한다면 Eat 객체와 Person 객체는 거의 독립적인 객체가 된다. Eat 객체를 수정하거나 Person 객체를 수정한다고 해서 상대 객체를 함께 수정해야 하는 문제를 방지할 수 있다.

let menu = Eat(Coffee: "아메리카노", meal: "피자")
let anotherMenu = Eat(Coffee: "라떼", meal: "햄버거")
var personTest = Person(todayEat: menu)

personTest.printCoffee()  // 아메리카노
personTest.chanfeMenu(menu: anotherMenu)
personTest.printCoffee()  // 라떼
profile
i♡S Developer

0개의 댓글