-
SOLID - Dependency inversion (의존성 역전법칙)파헤치기Java/디자인패턴 2024. 10. 22. 16:22반응형
Dependency inversion
**Dependency Inversion Principle (DIP)**는 SOLID 원칙 중 하나로, 고수준 모듈이 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다는 개념입니다. 즉, 상위 계층(High-level 클래스)이 하위 계층(Low-level 클래스)에서 세부 사항에 의존하지 않고, 둘 다 인터페이스나 추상 클래스와 같은 추상화에 의존해야 한다는 원칙입니다.
DIP를 위배한 코드
// Low-level class public class Fan { public void spin() { System.out.println("Fan is spinning"); } public void stop() { System.out.println("Fan is stopping"); } } // High-level class public class Switch { private Fan fan; public Switch(Fan fan) { this.fan = fan; } public void turnOn() { fan.spin(); } public void turnOff() { fan.stop(); } }
문제점:
위 코드에서 Switch 클래스(고수준 모듈)는 Fan 클래스(저수준 모듈)에 직접 의존하고 있습니다. 이는 DIP를 위반하는 구조입니다. 만약 Switch 클래스가 다른 종류의 장치를 제어해야 한다면, Switch 클래스를 변경해야만 합니다. 즉, Switch는 특정 구현 세부사항에 의존하고 있어, 확장성과 유지보수성이 떨어지게 됩니다.
개선 방법:
DIP를 준수하기 위해서는, Switch와 Fan이 추상화에 의존해야 합니다. 이를 위해, Fan과 같은 구체적인 클래스 대신 인터페이스를 사용하여 상위 모듈(Switch)과 하위 모듈(Fan)이 인터페이스에 의존하도록 변경할 수 있습니다. 그러면 Switch 클래스는 다른 장치를 제어할 때도 수정할 필요가 없습니다.
개선된 코드
// 추상화된 장치 인터페이스 public interface Switchable { void turnOn(); void turnOff(); } // Fan 클래스는 Switchable 인터페이스를 구현 public class Fan implements Switchable { @Override public void turnOn() { System.out.println("Fan is spinning"); } @Override public void turnOff() { System.out.println("Fan is stopping"); } } // Light 클래스는 Switchable 인터페이스를 구현 public class Light implements Switchable { @Override public void turnOn() { System.out.println("Light is on"); } @Override public void turnOff() { System.out.println("Light is off"); } } // Switch 클래스는 이제 Switchable 인터페이스에 의존 public class Switch { private Switchable device; public Switch(Switchable device) { this.device = device; } public void turnOn() { device.turnOn(); } public void turnOff() { device.turnOff(); } } // Main 클래스에서 다양한 장치를 제어 가능 public class Main { public static void main(String[] args) { Switchable fan = new Fan(); Switch fanSwitch = new Switch(fan); fanSwitch.turnOn(); // Fan is spinning fanSwitch.turnOff(); // Fan is stopping Switchable light = new Light(); Switch lightSwitch = new Switch(light); lightSwitch.turnOn(); // Light is on lightSwitch.turnOff(); // Light is off } }
개선된 코드 설명:
- Switchable 인터페이스: turnOn()과 turnOff() 메서드를 포함한 인터페이스로, 제어 가능한 모든 장치들이 이 인터페이스를 구현하도록 합니다. 이를 통해 상위 모듈(Switch)이 구체적인 장치(예: Fan, Light)가 아닌 추상화된 Switchable 인터페이스에 의존하게 만듭니다.
- Fan 클래스: 이제 Switchable 인터페이스를 구현하여, Fan은 Switchable 타입으로 다뤄집니다. 이로 인해 Switch 클래스는 더 이상 구체적인 Fan 클래스에 의존하지 않습니다.
- Light 클래스: 새로운 장치(Light)도 Switchable 인터페이스를 구현합니다. Switch 클래스는 Light를 제어할 때도 기존 로직을 그대로 사용할 수 있습니다.
- Switch 클래스: 이 클래스는 더 이상 Fan과 같은 구체적인 구현에 의존하지 않고, Switchable 인터페이스에만 의존합니다. 따라서 다른 장치를 제어할 때도 코드를 수정할 필요가 없습니다.
DIP 준수:
이 설계는 **Dependency Inversion Principle (DIP)**를 준수합니다. 상위 모듈(Switch)과 하위 모듈(Fan, Light)이 모두 Switchable이라는 추상화에 의존하므로, 상위 모듈이 하위 모듈의 구체적인 구현에 의존하지 않게 됩니다. 이로 인해 코드가 더 확장 가능하고 유연하게 유지되며, 새로운 장치를 추가하거나 수정할 때 상위 모듈을 수정할 필요가 없습니다.
반응형'Java > 디자인패턴' 카테고리의 다른 글
Behavioral Design Pattern - Strategy(전략) 파헤치기 (0) 2024.10.25 Structural Patterns - 파사드(Facade) 파헤치기 (0) 2024.10.24 SOLID - Interface segregation(인터페이스 분리법칙) 파헤치기 (1) 2024.10.22 SOLID - Liskov substitution 리스코프 치환원칙 파헤치기 (0) 2024.10.22 SOLID - Open-Closed 개방폐쇄원칙 파헤치기 (0) 2024.10.22