저번에 배웠던 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 위반 ❌
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();`
⭐ DIP 위반 : 할인 정책의 클라이언트가 FixDiscountPolicy
라는 구체 클래스도 함께 의존하고 있다.
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// 할인 정책 변경
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
⭐ OCP 위반 : 할인 정책의 변경을 위해FixDiscountPolicy
를 RateDiscountPolicy
로 변경하면 기존 코드인 OrderServiceImpl
의 소스
코드도 함께 변경해야 한다.
public class OrderServiceImpl implements OrderService {
private DiscountPolicy discountPolicy;
}
👉 정말로 인터페이스에만 의존을 하네... 하지만 실행할 수는 없는...
🤔 정말 어떻게 해야할까?
다음에 이 코드의 문제가 무엇인지 알아보도록 하자~!