AR삽질러

Spring-등급제회원_기본예제DIP, OCP(5) 본문

JAVA/Spring

Spring-등급제회원_기본예제DIP, OCP(5)

아랑팡팡 2023. 6. 28. 14:50
728x90

RateDiscountPolicyTest

 

RateDiscountPolicy : 할인정책 클래스로 discountPercent변수에 할인율을 나타내고 VIP회원일 경우에만 할인을 적용한 값을 반환하고 그외는 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;
        }
    }
}

 

RateDiscountPolicyTest : JUnit프레임워크를 사용하여 단위테스트를 한다. vip_o의 경우 VIP회원일 경우 10%가 할인되는것을 테스트하고 vip_x의 경우 VIP회원이 아닐경우 할일이 적용되지 않는것을 테스트한다.

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(1L, "memberBASIC", Grade.BASIC);
        //when
        int discount = discountPolicy.discount(member, 1000);
        //then
        assertThat(discount).isEqualTo(0);
    }
}

 

DIP

 Dependency Inversion Principle

 DIP : 추상에 의존하지만 구체에 의존하지 않아야한다. 현재는 OrderServiceImple은 구체 클래스인 DiscountPolicy인터페이스에 의존하고 있지만 OrderServiceImpl은FixDiscountPolicy,RateDiscountPolicy에도 의존하고 있어 DIP를 위반한다.

 - DIP를 준수하도록 OrderServiceImpl의 생성자를 통해 DiscountPolicy구현체를 주입받도록 변경해야한다.

 

OCP

 Open-Closed Principle

 OCP : 기능 확장에는 열려 있어야하고 수정에는 닫혀 있어야한다. 현재는 새로운 할인 정책을 추가하려면 OrderServiceImple을 수정해야하지만 OCP위반이 된다. 따라서 클라이언트 코드변경이 필요하다.

 

DIP, OCP 를 준수한 코드수정

 

AppConfig는애플리케이션의실제동작에 필요한구현객체를생성한다.
 MemberServiceImpl, MemoryMemberRepository, OrderServiceImpl, FixDiscountPolicy
AppConfig는생성한 객체인스턴스의참조(레퍼런스)를생성자를 통해서주입(연결)해준다.
 MemberServiceImpl   MemoryMemberRepository, OrderServiceImpl   MemoryMemberRepository , FixDiscountPolicy

 

AppConfig 클래스를 구현하여 DI의존성 주입을 하고 DIP(Dependency Inversion Principle)를 준수한다.

 

MemberServiceImpl

public class MemberServiceImpl implements MemberService{
    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Override
    public void join(Member member){
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId){
        return memberRepository.findById(memberId);
    }
}

 

AppConfig

public class AppConfig {
    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

    public OrderService orderService() {
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
    }
}

 

OrderServiceImpl

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice){
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}
728x90
반응형
LIST