[스프링 핵심원리 기본편] 3.(1) 새로운 할인 정책 개발

코린이서현이·2023년 11월 10일
0

😑들어가면서😑

저번에 배웠던 OCP, DIP를 기억하시는가?! 네니요! 그러면 공부를 하면 된다. (*^-^*)
그전에 노래를 하나 추천해주고 싶다. 힘듦에 빠지는 데, 그러고 싶지 않을 때 들으면 좋을 것 같다.! 

디지몬 OST 버터플라이

📒 OCP : 개방-폐쇄 원칙

📌 "소프트웨어는 확장에는 열려있으나 변경에는 닫혀있어야한다."
👉 변경 시, 기존 코드를 변경하지 않아도 가능 해야한다.

📒 DIP : 의존 관계 역전 원칙

📌 구체화가 아닌, 추상화에 의존해야한다.
👉 구현과 역할을 나누고, 역할에 의존하게 해야한다.

🎯 목표

👤 : 할인 정책 바꾸고 싶어요. 10% 할인으로 할래요

📌 새로운 할인 정책 개발
📌 새로운 할인 정책 적용
📌 정책 적용 의 문제점
👉 어떻게 해야할까? 

📌 새로운 할인 정책 개발

할인 정책 구현

📄 RateDiscountPolish

  • 아까 만들었던 인터페이스 구현!
public class FixDiscountPolicy implements DiscountPolicy {

  private int discountFixAmount = 1000; //1000원 할인

  @Override
  public int discount(Member member, int price) {
    if (member.getGrade() == Grade.VIP) { //
      return discountFixAmount;
    } else {
      return 0;
    }
  }
}

테스트 코드 작성

📄 RateDiscountPolicyTest

class RateDiscountPolicyTest {
  RateDiscountPolicy discountPolicy = new RateDiscountPolicy();
  @Test
  @DisplayName("VIP는 10% 할인이 적용되어야 한다.") //화면에 보이게 하는 어노테이션
  void vip_o() {
    //given
    Member member = new Member(1L, "memberVIP", Grade.VIP);
    //when
    int discount = discountPolicy.discount(member, 10000);
    //then
    assertThat(discount).isEqualTo(1000);
  }
  @Test
  @DisplayName("VIP가 아니면 할인이 적용되지 않아야 한다.")
  void vip_x() {
    //given
    Member member = new Member(2L, "memberBASIC", Grade.BASIC);
    //when
    int discount = discountPolicy.discount(member, 10000);
    //then
    assertThat(discount).isEqualTo(0);
  }
}

➕ 어노테이션 @DisplayName

Junit5에서 들장한 어노테이션 : 테스트 클래스나, 테스트 메서드에 이름이나 설명을 넣을 수 있다.

📌 새로운 할인 정책 적용

👉 할인 정책의 클라이언트인 OderServiceImpl을 변경해야한다.

public class OrderServiceImpl implements  OrderService{
 //주문을 받은 다음, 회원 조회 , 할인 적용을 해야한다.
  private final MemberRepository memberRepository = new MemoryMemberRepository();
//  private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// 할인 정책 변경
  private final DiscountPolicy discountPolicy = new RateDiscountPolicy();

...?🤔 기존 코드를 바꾸는데? 이거 OCP를 위반하는데?

📌 위 코드의 문제점

  • 🚫 위에서! 할인정책을 바꾸려면 기존 코드인 OrderServiceImpl을 고쳐야한다.
    기능 변경을 위해 기존 코드를 수정하는 것은 OCP 위반 ❌

  • 🚫 OrderServiceImpl에서 인터페이스 뿐만 아니라 구체적인 구현에도 의존하고 있다.
    ➡️ 클래스 의존관계를 분석해 보자
    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    구현 클래스에서도 의존 하는 것은 DIP 위반 ❌

이 코드는 결국

  • 역할과 구현을 분리하였다.
  • 오버라이딩을 이용하여 다형성을 활용하였다.
  • 그러나 OCP나 DIP는 지키지 못했다.

실제 의존 관계의 다이어그램

private final DiscountPolicy discountPolicy = new FixDiscountPolicy();`

DIP 위반 : 할인 정책의 클라이언트가 FixDiscountPolicy라는 구체 클래스도 함께 의존하고 있다.

정책 변경 시 다이어그램

//  private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// 할인 정책 변경
  private final DiscountPolicy discountPolicy = new RateDiscountPolicy();

OCP 위반 : 할인 정책의 변경을 위해FixDiscountPolicyRateDiscountPolicy 로 변경하면 기존 코드인 OrderServiceImpl의 소스
코드도 함께 변경해야 한다.

👉 어떻게 해야할까?

  • DIP를 위반하지 않도록 인터페이스에만 의존하도록 설계를 변경한다.
public class OrderServiceImpl implements OrderService {
	private DiscountPolicy discountPolicy;
}

👉 정말로 인터페이스에만 의존을 하네... 하지만 실행할 수는 없는...

🤔 정말 어떻게 해야할까?

👋마지막으로👋

다음에 이 코드의 문제가 무엇인지 알아보도록 하자~!
profile
24년도까지 프로젝트 두개를 마치고 25년에는 개발 팀장을 할 수 있는 실력이 되자!

0개의 댓글