드디어 SOLID에 마지막 법칙인 DIP !
사실 DIP 없이는 OCP를 구현할 수 없다고 생각해서.. OCP를 완전히 이해하고 적용할 수 있는 사람이라면 DIP 개념이 어렵지 않을 것이라고 생각한다.
그렇지만 처음 본다면 상당히 어려운 개념.. 쉬운 비유와 예시를 통해 마스터 해보도록 하자 ;-;
Dependency Inversion Principle : 의존성 역전 법칙
이게 도대체 무슨 소리인가 싶지만.. 비유를 통해 차근차근 알아보자.
일단 시작에 앞서 상위 모듈은 컴퓨터, 하위 모듈은 키보드라고 해보자.
노트북은 내장되어 있는 빌트인 키보드에 절대적으로 의존하고 있다고 볼 수 있다.
키보드가 고장나면 노트북 사용에 큰 영향을 끼치고 다른 키보드로 바꿔끼기도 싶지 않다.
이 상황에서 첫번째 정의와 같이 상위 모듈이 하위 모듈에 의존하고 있다고 볼 수 있다.
그럼 다음으로 데스크탑에서의 키보드 사용을 살펴보자.
데스크탑은 어떤 키보드 자체를 의존하고 있는 것이 아닌 키보드의 신호가 들어오는 USB 포트를 의존하고 있다.
마찬가지로 키보드 입장에서도 데스크탑이 아닌 USB 포트를 의존하고 있다고 볼 수 있다.
각 모듈의 독립성은 유지한 채 USB포트라는 추상화를 바라봄으로써 상위 모듈과 하위 모듈은 추상화에 의존한다고 볼 수 있다.
이 때, 키보드가 고장나더라도 쉽게 다른 키보드로 교체할 수 있어 유연성과 확장성에 용이하다.
이 처럼, 실생활에서도 의존성이 낮아지면 좋은 이점을 많이 얻어갈 수 있다.
class BuiltInKeyboard {
func type() {
print("Typing on built-in keyboard")
}
}
class Laptop {
let keyboard = BuiltInKeyboard()
func useKeyboard() {
keyboard.type()
}
}
// 사용 예시
let myLaptop = Laptop()
myLaptop.useKeyboard()
// result
// "Typing on built-in keyboard"
코드에서 상위 모듈인 Laptop은 BuiltInKeyboard라는 하위 모듈을 완전히 의존하고 있는 상태이다.
이러면 Laptop 클래스는 BuiltInKeyboard클래스만을 위한 클래스가 되는 것이다.
이 것은 DIP가 위반된 것으로 상위 모듈과 하위 모듈 모두 추상화를 바라볼 수 있게 리팩토링 해줘야 한다.
만약, 기존 키보드를 새로운 키보드로 교체하여 사용하려고 하면 Laptop 코드의 변경이 일어나야 하므로 OCP 원칙을 위반한게 될 것이다.
// 추상화된 프로토콜
protocol Keyboard {
func type()
}
// 구체적인 구현 1: Normal 키보드
class NormalKeyboard: Keyboard {
func type() {
print("Typing on normal keyboard")
}
}
// 구체적인 구현 2: LED 키보드
class LEDKeyboard: Keyboard {
func type() {
print("Typing on led keyboard")
}
}
// 데스크탑 클래스는 추상화된 프로토콜에 의존
class Desktop {
var keyboard: Keyboard
init(keyboard: Keyboard) {
self.keyboard = keyboard
}
func useKeyboard() {
keyboard.type()
}
}
// 사용 예시
let normalKeyboard = NormalKeyboard()
let ledKeyboard = LEDKeyboard()
let myDesktopWithUSB = Desktop(keyboard: normalKeyboard)
myDesktopWithUSB.useKeyboard()
// result
// "Typing on USB keyboard"
let myDesktopWithBluetooth = Desktop(keyboard: ledKeyboard)
myDesktopWithBluetooth.useKeyboard()
// result
// "Typing on Bluetooth keyboard"
해당 코드에서는 프로토콜로 추상화를 구현하고 상위 모듈인 Desktop과 하위 모듈인 NormalKeyboard, LEDKeyboard가 모두 추상화를 의존하고 있는 형태이다.
DIP를 위반하지 않은 코드로, Desktop에서는 여러 형태의 키보드를 사용할 수 있으며 새로운 키보드로 교체 하여도 Desktop 코드에 영향을 끼치지 않으므로 OCP 원칙도 잘 지킨 것을 확인할 수 있다.
여기까지 실생활 비유와 코드 예시를 통해 DIP를 알아보았다.
처음에는 다소 생소한 원칙이지만 좋은 코드 구조를 위해서 꼭 필요한 원칙으로 실무에서도 적용하려는 습관을 들이려고 노력해야 한다.
추상화에 의존하라!!
모든 피드백 감사합니다. (꾸벅)