[SOLID] 의존성 역전 원칙(DIP)을 적용하지 않은 샘플과 적용한 샘플 비교

엔스마트·2024년 7월 3일

의존성 역전 원칙(Dependency Inversion Principle, DIP)은 고수준 모듈이 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다는 원칙입니다. 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.

의존성 역전 원칙을 적용하지 않은 샘플

아래 코드는 고수준 모듈이 저수준 모듈에 직접 의존하는 예제입니다.

Light.java (저수준 모듈)

public class Light {
    public void turnOn() {
        System.out.println("Light is turned on");
    }

    public void turnOff() {
        System.out.println("Light is turned off");
    }
}

Switch.java (고수준 모듈, DIP 미적용)

public class Switch {
    private Light light;

    public Switch(Light light) {
        this.light = light;
    }

    public void turnOn() {
        light.turnOn();
    }

    public void turnOff() {
        light.turnOff();
    }

    public static void main(String[] args) {
        Light light = new Light();
        Switch lightSwitch = new Switch(light);
        lightSwitch.turnOn();
        lightSwitch.turnOff();
    }
}

위 코드에서 Switch 클래스는 Light 클래스에 직접 의존하고 있습니다. 만약 다른 종류의 장치를 제어해야 한다면 Switch 클래스를 수정해야 합니다.

의존성 역전 원칙을 적용한 샘플

DIP를 적용하기 위해 인터페이스를 사용하여 고수준 모듈과 저수준 모듈이 추상화에 의존하도록 합니다.

Switchable.java (추상화)

public interface Switchable {
    void turnOn();
    void turnOff();
}

Light.java (저수준 모듈)

public class Light implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("Light is turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("Light is turned off");
    }
}

Fan.java (저수준 모듈)

public class Fan implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("Fan is turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("Fan is turned off");
    }
}

Switch.java (고수준 모듈, DIP 적용)

public class Switch {
    private Switchable device;

    public Switch(Switchable device) {
        this.device = device;
    }

    public void turnOn() {
        device.turnOn();
    }

    public void turnOff() {
        device.turnOff();
    }

    public static void main(String[] args) {
        Switchable light = new Light();
        Switch lightSwitch = new Switch(light);
        lightSwitch.turnOn();
        lightSwitch.turnOff();

        Switchable fan = new Fan();
        Switch fanSwitch = new Switch(fan);
        fanSwitch.turnOn();
        fanSwitch.turnOff();
    }
}

비교 분석

DIP 미적용 코드의 문제점:

  • 유연성 부족: Switch 클래스가 Light 클래스에 직접 의존하므로, 다른 종류의 장치를 제어하려면 Switch 클래스를 수정해야 합니다.
  • 재사용성 부족: Switch 클래스는 Light 클래스와 강하게 결합되어 있어, 다른 장치를 추가하려면 많은 수정을 해야 합니다.

DIP 적용 코드의 장점:

  • 유연성 향상: Switch 클래스가 Switchable 인터페이스에 의존하므로, 다른 종류의 장치를 제어할 수 있습니다. 새로운 장치를 추가할 때 Switch 클래스를 수정할 필요가 없습니다.
  • 재사용성 향상: Switch 클래스는 인터페이스에 의존하므로, 다양한 장치와 함께 사용할 수 있습니다. 이는 코드의 재사용성을 높입니다.
  • 테스트 용이성: Switchable 인터페이스를 통해 모의 객체(mock object)를 쉽게 만들 수 있어, 단위 테스트를 작성하기 용이합니다.

결론

의존성 역전 원칙을 준수하면 코드의 유연성과 재사용성이 크게 향상됩니다. 고수준 모듈과 저수준 모듈이 추상화에 의존하도록 설계하면, 변경에 유연하고 유지보수가 용이한 코드를 작성할 수 있습니다. 따라서 소프트웨어 개발에서 DIP를 준수하는 것이 중요합니다.

profile
클라우드 전환, MSA 서비스, DevOps 환경 구축과 기술지원 그리고 엔터프라이즈 시스템을 구축하는 최고 실력과 경험을 가진 Architect Group 입니다.

0개의 댓글