객체 지향 원리 적용

새로운 할인 정책

악덕 기획자: 서비스 오픈 직전에 할인 정책을 지금처럼 고정 금액 할인이 아니라 좀 더 합리적인 주문 금액 당 할인하는 정률 % 할인으로 변경하고 싶어요. 
예를 들어서 기존 정책은 VIP가 10000원을 주문하든 20000원을 주문하든 항상 1000원을 할인했는데, 이번에 새로 나온 정책은 10%로 지정해두면
고객이 10000원 주문시 1000원을 할인해주고, 20000원 주문시에 2000원을 할인해주는 거에요!

순진 개발자: 제가 처음부터 고정 금액 할인은 아니라고 했잖아요.

악덕 기획자: 애자일 소프트웨어 개발 선언 몰라요? “계획을 따르기보다 변화에 대응하기를”

순진 개발자: ... (하지만 난 유연한 설계가 가능하도록 객체지향 설계 원칙을 준수했지 후후)

객체 지향적으로 설계했다면 RateDiscountPolicy로 바꾸기만 하면 될 것이다. 확인해보자.

새로운 할인 정책 적용과 문제점

할인 정책을 변경하려면 클라이언트인 OrderServiceImpl 코드를 FixDiscountPolicy에서 RateDiscountPolicy로 고쳐야 한다.

우리는 역할과 구현을 충실하게 분리했다. 다형성도 활용하고 인터페이스와 구현 객체를 분리했다. OCP, DIP 같은 객체 지향 설계 원칙은 충실히 준수한 것 같지만 사실은 아니다.

DIP

클래스 의존 관계를 분석해보면 추상(인터페이스) DiscountPolicy 뿐만 아니라 구체(구현) FixDiscountPolicy, RateDiscountPolicy 클래스에도 의존하고 있다.

지금까지는 단순히 DiscountPolicy 인터페이스에만 의존한다고 생각했다.

하지만 잘 보면 클라이언트인 OrderServiceImplDiscountPolicy뿐만 아니라 구체 클래스인 FixDiscountPolicy도 의존하고 있다. DIP를 위반하는 것이다.

OCP

OrderServiceImpl이 인터페이스만 보는 게 아니라 FixDiscountPolicy도 보고 있기 때문에 RateDiscountPolicy로 변경하는 순간 OrderServiceImpl의 소스 코드도 함께 변경해야 한다.

기능을 확장해서 변경하면 클라이언트 코드에 영향을 주므로 OCP를 위반한다.

기름차를 전기차로 변경했는데 라이센스를 다시 따야하는 상황이 온 것이다.

어떻게 해결할 수 있을까?

인터페이스에만 의존하도록 설계를 변경하자.

인터페이스에만 의존하도록 설계와 코드를 변경했다. 그런데 구현체가 없는 상태에서 코드를 실행하면 NPE가 발생한다.

이 문제를 해결하려면 누군가가 클라이언트인 OrderServiceImplDiscountPolicy의 구현 객체를 대신 생성하고 주입해줘야 한다.

Last updated

Was this helpful?