->요구사항 발생으로 개발 수정이 필요한 상황, 객체지향 원칙을 지켜가면서 수정이 가능할까?
package springbasic.core.discount;
import springbasic.core.member.Grade;
import springbasic.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;
}
}
}
package springbasic.core.discount;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import springbasic.core.member.Grade;
import springbasic.core.member.Member;
import static org.assertj.core.api.Assertions.assertThat;
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
assertThat(discount).isEqualTo(1000);
}
@Test
@DisplayName("VIPx 할인적용x")
void vip_x(){
//given
Member member = new Member(2L,"memberBASIC", Grade.BASIC);
//when
int discount = discountPolicy.discount(member,10000);
//then
assertThat(discount).isEqualTo(0);
}
}
(*ctrl+shift+t로 테스트코드.java 자동생성 가능)
-> 할인 정책을 변경하려면 클라이언트인 OrderServiceImpl 코드를 고쳐야함
문제점이 무엇이지?
- 역할과 구현을 충실히 분리했는가? ok
- 다형성 활용 및 인터페이스 구현 객체를 분리했는가? ok
- OCP,DIP같은 객체지향 설계 원칙을 충실히 준수하였는가? .....no
-> DIP 위반 : OrderServiceImpl은 추상(DiscountPolicy)뿐만 아니라 구현클래스(FixDiscountPolicy)에도 의존하고있음
-> OCP 위반 : 현재 코드는 기능확장 위해 변경 시 클라이언트에 영향 줌
4. 어떻게 적용해야 문제가 해결될까?
설계 변경
소스 수정
- 정리
-> 인터페이스에만 의존하도록 설계와 코드 변경
--> "구현체가 없어서 코드 실행이 되지 않는다!(NullPointException)
---> 누군가가 클라이언트에 구현객체를 대신 생성 및 주입해주어야 한다.