객체지향

[객체지향] SOLID(5) - DIP(의존관계 역전 원칙)

재담 2022. 3. 1. 23:34

DIP(Dependency Inversion Principle)

의존관계 역전 원칙이란 구체화된 클래스가 아닌 인터페이스나 추상 클래스에 의존해야 한다는 것을 말한다. 인터페이스나 추상 클래스와 관계를 맺음으로 변화하기 쉬운 것(일반 클래스)으로부터 의존을 줄인다. 의존관계 역전 원칙을 따르면, 상위 계층(정책 결정)이 하위 계층(세부 사항)에 의존하는 전통적인 의존관계를 반전(역전) 시킴으로써 상위 계층이 하위 계층의 구현으로부터 독립되게 할 수 있다. 이 원칙은 다음과 같은 내용을 담고 있다.

  • 상위 모듈은 하위 모듈에 의존해서는 안 된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.
  • 추상화는 세부 사항에 의존해서는 안 된다. 세부 사항이 추상화에 의존해야 한다.

 

의존관계 역전 원칙은 '상위와 하위 객체 모두가 동일한 추상화에 의존해야 한다'는 객체 지향적 설계의 대원칙을 제공한다.

 

DIP의 예시를 살펴보자.

public class SummerTyre {
    public void run() {
        System.out.println("Run with Summer Tyre");
    }
}
public class Car {
    private final SummerTyre summerTyre;

    public Car(SummerTyre summerTyre) {
        this.summerTyre = summerTyre;
    }
}

위 코드에서 Car 클래스는 SummerTyre 클래스에 의존하고 있다. 이와 같은 상황에서 SnowTyre 클래스나 SeasonTyre 클래스가 추가된다고 한다면, Car 클래스의 SummerTyre 변수를 변경해야 할까? 그렇게 하기보다는 다음과 같이 SummerTyre 클래스를 추상화하여 Car 클래스는 Tyre 인터페이스에 의존하는 것이 바람직해 보인다.

public interface Tyre {
    String tyreType();
}
public class SummerTyre implements Tyre {
    @Override
    public String tyreType() {
        return "SummerTyre";
    }
}
public class SnowTyre implements Tyre {
    @Override
    public String tyreType() {
        return "SnowTyre";
    }
}
public class SeasonTyre implements Tyre {
    @Override
    public String tyreType() {
        return "SeasonTyre";
    }
}
public class Car {
    private final Tyre tyre;

    public Car(Tyre tyre) {
        this.tyre = tyre;
    }
    
    public void drive() {
        System.out.println(tyre.tyreType());
    }
}
public class Main {
    public static void main(String[] args) {
        Car car = new Car(new SeasonTyre());
        car.drive();
    }
}

Reference