오봉이와 함께하는 개발 블로그
Spring - 스프링 핵심 원리 이해2 - 1(객체 지향 원리 적용) 본문
728x90
새로운 할인 정책
- 기존 고정 1000원 할인에서 금액에 따라 10% 할인으로 변경
RateDiscountPolicy 추가
RateDiscountPolicy 코드
package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
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;
}
}
}
RateDiscountPolicy 테스트
package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
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
Assertions.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
Assertions.assertThat(discount).isEqualTo(0);
}
}
새로운 할인 정책 적용과 문제점
할인 정책 적용
할인 정책을 변경하려면 클라이언트인 OrderServiceImpl을 고쳐야 함.
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}
문제점
- 역할과 구현을 충실하게 분리했다 -> OK
- 다형성 활용, 인터페이스와 구현 객체 분리 -> OK
- OCP, DIP 같은 객체지향 설계 원칙을 충실히 준수했다. -> NO
- DIP
- 주문서비스 클라이언트(OrderServiceImpl)는 인터페이스뿐만 아니라 구현 클래스에도 의존하고 있다
- 인터페이스 의존 : DiscountPolicy
- 구현 클래스 : FixDiscountPolicy, RateDiscountPolicy
- 주문서비스 클라이언트(OrderServiceImpl)는 인터페이스뿐만 아니라 구현 클래스에도 의존하고 있다
- DIP
기대했던 의존
실제 의존
DIP 위반!!!
정책 변경
FixDiscountPolicy 를 RateDiscountPolicy 로 변경하는 순간 OrderServiceImpl 의 소스 코드도 함께 변경 -> OCP 위반
public class OrderServiceImpl implements OrderService{
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}
어떻게 문제를 해결?
- 클라이언트 코드(OrderServiceImpl)은 DiscountPolicy의 인터페이스 뿐만 아니라 구체 클래스도 함께 의존
- 구체 클래스를 변경하려면 클라이언트 코드도 함께 변경해야 한다.(정책 변경 참고)
- DIP 위반 -> 인터페이스만 의존하도록 변경
인터페이스에만 의존하도록 변경
public class OrderServiceImpl implements OrderService {
//private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
private DiscountPolicy discountPolicy;
}
- 구현체가 없기 때문에 실행하면 null pointer exception 발생!
해결 방안
- 누군가가 클라이언트인 OrderServiceImpl에 DiscountPolicy의 구현 객체를 대신 생성하고 주입해주어야 한다.
출처 : 인프런 김영한 지식공유자님의 스프링 완전 정복 로드맵 강의
728x90
'BE > Spring' 카테고리의 다른 글
Spring - 스프링 핵심 원리 이해2 - 3(객체 지향 원리 적용) (0) | 2022.06.03 |
---|---|
Spring - 스프링 핵심 원리 이해2 - 2(객체 지향 원리 적용) (0) | 2022.06.02 |
Spring - 이해를 위해 순수 Java로 작성하는 예제(3)(스프링 핵심 원리 이해1 예제 만들기) (0) | 2022.05.31 |
Spring - 이해를 위해 순수 Java로 작성하는 예제(2)(스프링 핵심 원리 이해1 예제 만들기) (0) | 2022.05.30 |
Spring - 이해를 위해 순수 Java로 작성하는 예제(1) (스프링 핵심 원리 이해1 예제 만들기) (0) | 2022.05.30 |
Comments