
고수준 모듈(왼) 과 저수준 모듈(오)
고수준 모듈이 저수준 모듈에 의존하면 안 되고, 추상화(인터페이스)에 의존해야 한다.
고수준 모듈이 저수준 모듈을 사용하면 구현 변경과 테스트가 어려워지는 문제가 생김
DIP는 저수준 모듈이 고수준 모듈에 의존하도록 변경
public class OrderService {
private final KakaoTalkNotifier kakaoTalkNotifier;
public OrderService() {
this.kakaoTalkNotifier = new KakaoTalkNotifier();
}
public void placeOrder() {
// 주문 로직...
kakaoTalkNotifier.send("주문 완료");
}
}
orderService가 직접 KakaoTalkNotifier에 의존함
즉 고수준 모듈이 저수준 모듈(구현)에 끌려다님
//인터페이스
public interface Notifier {
void send(String message);
}
// 인터페이스 구현체 - 카카오 알림
public class KakaoTalkNotifier implements Notifier {
public void send(String message) {
// 실제 전송
}
}
// 인터페이스 구현체 - 이메일 알림
public class EmailkNotifier implements Notifier {
public void send(String message) {
// 실제 전송
}
}
// 고수준 모듈
public class OrderService {
private final Notifier notifier;
public OrderService(Notifier notifier) {
this.notifier = notifier;
}
public void placeOrder() {
// 주문 로직...
notifier.send("주문 완료");
}
}
고수준 모듈인 OrderService는 알림을 kakao로 했는지 email로 했는지
중요하지 않고 주문 완료 알림을 send에만 관심을 갖으면 된다.
즉 인터페이스는 "누가 사용하느냐" 기준으로 만들어야 하고, DIP는 사용하는 쪽(고수준)이 주도권을 가져야 한다는 원칙이다.
비즈니스 목적이 주도한 쪽이 고수준
비즈니스 목적을 실현하기 위한 도구가 저수준
DIP를 적용하면 응용 영역과 도메인 영역에 영향을 최소화하면서 구현체를 변경하거나 추가 할 수 있다.