[IOS - Swift] DI (의존성 주입)

서프로·2023년 5월 9일
0

의존성 주입이란 무엇일까?
의존성 주입은 거의 모든 객체지향 프로그래밍 언어에서 찾아볼 수 있다.
의존성 주입이 무엇을 의미하는지, 왜 필요한지 알아보자.

Dependency

Dependency는 무엇이냐?

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

예제 코드로 보자.

struct Me {
    private let coffee = Coffee()
    
    func startToday() {
        self.coffee.drink()
    }
}

Me 구조체에서 startToday 메소드를 호출할려면 Coffee 구조체가 필요하다.
이때 Me 구조체는 Coffee구조체의 의존성을 가진다라고 표현한다.
위 코드에서 coffee의 drink 메소드가 삭제되거나 변경되면 Me 구조체의 startToday 메소드도 변경되어야 한다.
즉, 코드의 재사용성이 떨어지고 결합도가 올라간다고 할 수 있다.

Injection

Injection은 무엇이냐?

외부에서 객체를 생성해서 넣는 것을 의미한다.

예제 코드로 보자.

struct Me {
    private let coffee: Coffee
    
    init(coffee: Coffee) {
        self.coffee = coffee
    }
    
    func startToday() {
        self.coffee.drink()
    }
}


let coffee = Coffee()
let me = Me(coffee: coffee)
me.startToday()

코드를 보면 Coffee객체를 외부에서 생성하여 Me 객체가 생성될 때 넣어주고 있다.
이것을 Injection이라고 한다.하지만, 이것 만으로 의존성이 줄어들었다고 할 수 없다.
첫 예제와 같이 Coffee객체의 drink메소드가 삭제되거나 변경된다면 Me객체에서 영향을 받게된다.

Dependency Injection

위의 예제 코드들 처럼, 의존성을 가진 코드가 많다면 재활용성이 떨어지고, 의존성을 가지는 객체들과 함께 수정해야 하는 문제가 생긴다. 이러한 점을 해결하기 위해 나온 개념이 바로 의존성 주입이다.

의존성 주입으로 생기는 이점

  • Unit Test가 용이해진다.
  • 코드의 재활용성을 높여준다.
  • 객체 간의 의존성을 줄이거나 없앨 수 있다.
  • 객체 간의 결합도를 낮추면서 유연한 코드를 작성할 수 있다.

Dependency Inversion Principle

의존 관계 역전 법칙, 줄여서 DIP말한다.
DIP는 객체 지향 프로그래밍 설계의 다섯가지 기본 원칙(SOLID)중 하나이다.
DIP의 핵심은 구체적인 객체는 추상화된 객체에 의존 해야 한다는 것이다.

예제 코드로 보자.

protocol Menu {
    func drink()
}

Swift에는 추상화된 객체를 다루는 Protocol이 있다.
Protocol을 사용하여 위와같이 drink메소드를 가진 추상화된 객체를 만들었다.

struct Coffee: Menu {
    var coffeeName: String
    
    init(coffeeName: String) {
        self.coffeeName = coffeeName
    }
    
    func drink() {
        print("\(self.coffeeName)를 마신다")
    }
}

이후 위와 같이, Coffee 구조체에서 Menu 프로토콜을 채택 후, drink메소드를 실체화 시켜주었다.

struct Me {
    var todayCoffee: Menu
    
    
    func startToday() {
        self.todayCoffee.drink()
    }
    
    mutating func changeTodayCoffee(menu: Menu) {
        self.todayCoffee = menu
    }
}

위를 보면 기존의 Coffee 객체에 의존하는 것이 아닌 Menu라는 추상적인 객체에 의존하게된다.
또한, changeTodayCoffee 메소드를 활용해서 의존성을 주입시킬 수 있다.

위의 코드들을 보면 Coffee객체와 Me객체는 거의 독립적인 객체가 된것을 확인할 수 있다.

let coffee = Coffee(coffeeName: "아메리카노")
let anotherCoffee = Coffee(coffeeName: "라떼")

var me = Me(todayCoffee: coffee)
me.startToday()
me.changeTodayCoffee(menu: anotherCoffee)
me.startToday()

0개의 댓글