minOS

스프링 핵심 원리 이해2 - 객체 지향 원리 적용(1) 본문

TIL/김영한의 스프링 핵심 원리

스프링 핵심 원리 이해2 - 객체 지향 원리 적용(1)

minOE 2024. 1. 18. 22:01
728x90

새로운 할인 정책 개발

public class FixDiscountPolicy implements DiscountPolicy {
    private int discountFixAmount = 1000;

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


원래 할인 정책에서 새로운 할인 정책 하나를 추가했습니다.

public class RateDiscountPolicy implements DiscountPolicy{
    private int discountPercent =10;
    @Override
    public int discount(Member member, int price) {
        if(member.getGrade()== Grade.VIP)
            return price * discountPercent/100;
        else
            return 0;
    }
}


새로운 할인 정책 테스트 코드

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);

    }

 




 

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

할인 정책을 변경하려면 클라이언트 'OrderServiceIml'을 고쳐야한다.
public class OrderServiceImpl implements OrderService{

   // private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
    }​


문제점
1) 우리는 역할과 구현을 충실하게 분리했다. o
2) 다형성도 활용하고, 인터페이스와 구현 객체를 분리했다. o
3) OCP,DIP같은 객체지향 설게 원칙을 충실히 준수하지 못했다.
 - DIP : 주문 서비스 클라이언트('OrderServiceIml') 은 'DiscountPolicy'인터페이스에 의존하면서 DIP를 지킨 것 같지만,
              -> 클래스 의존 관계를 분석해보면 추상(인터페이스)뿐만 아니라, 구체(구현)클래스에도 의존하고 있다.
              추상 인터페이스 의존 : DiscountPolicy
              구체,구현 클래스에 의존 : FixDiscountPolicy,RateDiscountPolicy
     
 - OCP : 변경하지 않고 확장할 수 있어야 하지만 지금 코드는 기능을 확장하면 클라이언트 코드에 영    향을 준다 따라서 OCP를 위반한다.

기대한 의존 관계 설계도


   

실제 의존 관계 설계도

클라이언트인 "OrderServiceIml" 이 "DiscountPolicy" 인터페이스 뿐만 아니라 "FixDiscountPolicy"인 구체 클래스도 함께 의존하고 있으므로 DIP 위반한 것이다.

"FixDiscountPolicy"를 "RateDiscountPolicy"로 변경하는 순간 "OrderServiceIml"의 소스도 함께 변경해야한다.
OCP 위반한 것이다.

 

 

인터페이스에만 의존하도록 코드 변경

 

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository = new MemoryMemberRepository();
    private  DiscountPolicy discountPolicy;
    }​

                        구현체가 없어서 NullPointerException 오류 발생

해결방안( DIP , OCP 원칙 모두 지키는 )
문제를 해결하려면 누군가는 클라이언트의  "OrderServiceIml"에 "DiscountPolicy"의 구현 객체를 대신 생성하고 주입해주어야 한다.

 

 

728x90