왕논의 연구실

의존성 역전 원칙(DIP)이란? 본문

iOS/Swift

의존성 역전 원칙(DIP)이란?

ywangnon 2025. 3. 17. 23:57

✅ 의존성 역전 원칙(Dependency Inversion Principle, DIP)

의존성 역전 원칙은 SOLID 원칙 중 하나로, "고수준 모듈이 저수준 모듈에 의존하면 안 된다" 는 개념을 의미합니다. 대신, 추상화(인터페이스 또는 프로토콜)에 의존해야 합니다.

📌 DIP 원칙의 정의

  1. 고수준 모듈(High-level Module)은 저수준 모듈(Low-level Module)에 의존하면 안 된다.
    • 둘 다 추상화(인터페이스 또는 프로토콜)에 의존해야 한다.
  2. 추상화는 구체적인 구현에 의존하면 안 된다.
    • 즉, 구체적인 클래스가 아닌 프로토콜를 바라봐야 한다.

🔥 DIP를 적용하지 않았을 때 발생하는 문제점

DIP를 적용하지 않으면, 고수준 모듈이 저수준 모듈을 직접 참조하게 되어 코드가 변경에 취약해집니다.

❌ DIP 위반 코드 예제 (나쁜 코드)

class Keyboard {  // ⬇️ 저수준 모듈
    func type() {
        print("Typing on keyboard")
    }
}

class Computer {  // ⬆️ 고수준 모듈
    private let keyboard: Keyboard  // 🔴 Keyboard에 직접 의존 (DIP 위반)

    init() {
        self.keyboard = Keyboard()
    }

    func useKeyboard() {
        keyboard.type()  // 🔴 직접 호출 (DIP 위반)
    }
}

📌 문제점

  • Computer(고수준 모듈) 클래스가 Keyboard(저수준 모듈) 클래스에 직접 의존하고 있음
  • 만약 Keyboard 대신 WirelessKeyboard를 사용하려면 Computer 코드를 직접 수정해야 함
  • 유연성이 부족하고 유지보수가 어려운 코드가 됨

✅ DIP를 적용한 코드 (좋은 코드)

✨ 해결 방법: 프로토콜을 이용하여 의존성을 역전

protocol InputDevice {  // 🔄 추상화 (프로토콜)
    func type()
}

class Keyboard: InputDevice {  // ⬇️ 저수준 모듈
    func type() {
        print("Typing on keyboard")
    }
}

class WirelessKeyboard: InputDevice {  // ⬇️ 또 다른 저수준 모듈
    func type() {
        print("Typing on wireless keyboard")
    }
}

class Computer {  // ⬆️ 고수준 모듈
    private let inputDevice: InputDevice  // ✅ 프로토콜에 의존

    init(inputDevice: InputDevice) {
        self.inputDevice = inputDevice
    }

    func useInputDevice() {
        inputDevice.type()  // ✅ 프로토콜를 통한 호출 (DIP 준수)
    }
}

// ✅ 실행 예제
let keyboard = Keyboard()
let computer1 = Computer(inputDevice: keyboard)
computer1.useInputDevice() // "Typing on keyboard"

let wirelessKeyboard = WirelessKeyboard()
let computer2 = Computer(inputDevice: wirelessKeyboard)
computer2.useInputDevice() // "Typing on wireless keyboard"

📌 DIP를 준수한 이유
✔️ Computer 클래스는 Keyboard를 직접 참조하지 않음
✔️ 대신 프로토콜(InputDevice)을 통해 간접적으로 의존
✔️ 새로운 입력 장치(WirelessKeyboard)를 추가해도 기존 코드 수정이 필요 없음


🎯 고수준 모듈 vs 저수준 모듈

DIP를 이해하려면 고수준 모듈과 저수준 모듈의 차이를 명확하게 알아야 합니다.

좋은 질문이에요! 고수준 모듈(High-level Module)과 저수준 모듈(Low-level Module)의 차이를 확실히 이해하면 의존성 역전 원칙(DIP) 이 왜 중요한지 더 명확해질 거예요.


🎯 고수준 모듈 vs 저수준 모듈

✅ 1. 고수준 모듈 (High-level Module)

  • 비즈니스 로직이나 핵심 기능을 담당하는 중요한 클래스
  • 다른 모듈을 사용하는 입장
  • 일반적으로 여러 개의 저수준 모듈을 조합하여 동작

💡 예제

  • Computer (컴퓨터 전체를 관리하는 클래스)
  • PaymentProcessor (결제를 처리하는 핵심 비즈니스 로직)
  • OrderManager (주문을 관리하는 시스템)

✅ 2. 저수준 모듈 (Low-level Module)

  • 세부적인 기능을 구현하는 클래스
  • 다른 모듈에 의해 사용되는 입장
  • 직접적인 하드웨어 조작 또는 데이터 입출력을 담당하는 경우가 많음

💡 예제

  • Keyboard, Mouse (입력 장치)
  • CreditCardPayment, PayPalPayment (결제 모듈)
  • DatabaseConnector (DB와 직접 연결하는 클래스)

구분 설명 예제
고수준 모듈 비즈니스 로직 담당, 다른 모듈을 사용 Computer, OrderManager, PaymentProcessor
저수준 모듈 세부적인 기능을 구현, 직접 사용됨 Keyboard, DatabaseConnector, PayPalPayment
추상화 (프로토콜) 고수준과 저수준을 분리하는 역할 InputDevice, PaymentMethod

 

💡 즉, "고수준 모듈은 저수준 모듈을 직접 참조하지 않고, 추상화를 통해 접근해야 한다."


💡 DIP 원칙의 핵심 정리

✔️ "고수준 모듈이 저수준 모듈을 직접 호출하면 안 된다."
✔️ 대신 프로토콜을 통해 호출해야 한다.
✔️ DIP를 적용하면 유연성과 유지보수성이 증가한다.