import UIKit
class Person {
var name: String
init(name: String) {
self.name = name
}
}
// Person에 name "바지" 주입
let 사람 = Person(name: "바지")
Person(name: "바지") 이부분이 바로 의존성을 주입해주는 것입니다. 외부에서 name에 값을 주고 있으니까요.
그럼 이제 의존성주입이 무엇인지 간단히 알아봤으니 왜 의존성 역전이 필요한지 알아보겠습니다.
아래와 같은 코드가 있다고 합시다.
위코드와 같이 커피메뉴는 베이스인 물에 의존적입니다. 의존적이라는게 무슨뜻이냐면 커피메뉴의 베이스의 타입은 물입니다.
커피메뉴는 커피이름함수에서 베이스.name으로 물의 변수에 접근하고 있죠. 만약 물의 변수이름인 name이 변경된다면 ???
위와 같이 오류가 발생하게되면서 커피메뉴또한 바뀌어야 합니다.
위와같이 물의 변수명이였던 name이 변경되었기 때문에 커피메뉴 또한 바꾸어 줘야합니다. 아래와 같이 말이죠
베이스가 우유로 바뀐다면요 ?? 다시 커피메뉴를 수정해야합니다.
위와같이 커피메뉴는 베이스에 의존적입니다. 베이스가 바뀌면 커피메뉴 또한 바뀌어야 하죠. 그림으로 보자면 이와 같습니다.
위에서 보았던대로 커피메뉴는 베이스가 다른 타입으로 바뀌거나 베이스의 수정이 일어난다면 자신의 코드도 바뀌어야하는 문제점이 있습니다. 이를 해결하기 위한것이 의존성 주입입니다.
의존성 주입 ?
기존의 의존성을 개선하여 의존성을 외부에서 주입할 수 있는 방식
의존성 주입의 장점 / 사용하는 이유 ?
- 객체 간의 의존성을 줄여 코드의 재활용성 / 확장성 증가
- 객체 간의 결합도가 낮아져 유연한 코드 / 유연한 프로그램을 작성 가능 (응집도는 높게 결합도는 낮게)
- 유지 보수가 쉬워짐
객체지향 프로그래밍 5대원칙 중 하나인 DIP
- 추상화된 것은 구체적인 것에 의존하지 말아야하며 구체적인것은 추상화된 것에 의존해야 한다.
Swift에서 추상화된 객체는 바로 프로토콜을 의미하죠. 그럼 위의 코드를 프로토콜을 사용하여 수정해 봅시다.
이제 커피메뉴는 추상화된 베이스프로토콜의존하고 있기 때문에 베이스가 물로 바뀌든 우유로 바뀌든 수정해야할 필요가 없어집니다.
이제는 오히려 물과 우유가 베이스프로토콜에 의존하고 있습니다. 위를 그림으로 바꾸어본다면 아래와 같을겁니다.
의존관계가 역전된것을 확인해 볼 수 있습니다. 이처럼 이제 커피메뉴는 추상화된 객체인 베이스 프로토콜에 의존하고 있고 물과 우유에 더이상 의존하지 않습니다. 반대로 물과 우유는 이제 추상화된 객체인 베이스프로토콜에 의존하고 있어 의존관계의 역전이 일어난것을 확인할 수 있습니다.