[Spring] DIP, OCP 사용 의미 이해

Big0·2022년 8월 12일
0
post-thumbnail

"본 게시글은 김영한님의 '스프링 핵심 원리 기본편'을 기반으로 작성된 글입니다."

스프링을 공부하다 보면 가장 처음에 DIPOCP를 마주한다. 내가 처음 자바를 접하고 스프링 프레임워크를 공부해보려고 강의를 듣다가 DIP와 OCP를 마주쳤을 때는 '아 그냥 이런 거구나~' 하고 정확히 지나쳤다. 현재까지 두 개의 프로젝트를 진행하면서 사용하기에만 급급했지, '어떤 원리로 이렇게 동작하며, 이게 이렇게 필요하구나~'하는 부분이 부족했다. 정확하게 이해하고 쓴 게 아니었다. 이번 기회에 스프링의 뼈대가 되는 이 부분을 확실하게 정리하고 공부할 필요가 있겠다는 생각이 들어 정리해본다.

OCP(Open/Close Principle)

자신의 확장에는 열려있어야 하고, 주변의 변화에는 닫혀있어야 한다.

DIP(Dependency Inversion Principle)

고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 된다. 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.


위 말에서 조금 더 부연설명을 하자면, 기획자가 개발자한테 '우리 서비스 할인 정책을 추가 해야돼요!'라고 한다면, 댓글 기능을 추가하는 로직 외에 다른 부분이 수정되면 안 된다. 이는 인터페이스(Interface)를 사용하면 쉽게 구현 가능하다.


만약 '고정 할인 정책(FixDiscountPolicy)'과 '퍼센트 할인 정책(RateDiscountPolicy)' 이 두가지가 있다고 해보자. DIP원칙이 지켜지지 않았다면? OrderServiceImpl이 각각의 정책을 '직접' 참조했을 것이다. 하지만 DIP원칙을 사용한다면 인터페이스 'DiscountPolicy'를 두어 두 정책을 구현체로 만든다. OrderServiceImpl은 DiscountPolicy만 참조하면 되며, 구체적인 구현체를 참조할 일이 없어진다.

또한 자연스럽게 OCP 원칙까지 가져가게 되는데, 인터페이스가 없었다면 OrderServiceImpl에서 각각의 정책을 직접 참조하여, 할인 정책이 변경되면 OrderServiceImpl의 코드까지 변경해야 하는 상황이 발생한다. 하지만 인터페이스 DiscountPolicy를 앞에 둔다면 OrderService는 구체적으로 어떤 정책인지 알 필요가 없게 해준다. 이는 OrderServiceImpl의 코드 수정 없이 새로운 정책을 추가할 수 있다는 말이다.

만약 기획자가 또 새로운 할인 정책을 만들어달라고 요청한다면, XXXDiscountPolicy만 추가하면 될 것이다. (세 할인 정책 모두 discount()라는 메서드를 갖고 있다고 해보자.)이는 모두 같은 discount()를 호출하지만 어떤 할인정책인지 OrderService에서는 알 필요가 없는 것이다.

0개의 댓글