도메인 설계 변경(추가)하기 (Feat. 제네릭)

myeonji·2022년 2월 10일
0

Spring

목록 보기
14/22

📌 할인정책 요구사항

  • 할인 기준 : 회원 등급에 따라 할인 정책을 적용할 수 있다.
  • 할인 정책은 모든 VIP는 1000원을 할인해주는 고정 금액 할인을 적용해달라. (나중에 변경 될 수 있다.)
  • 할인 정책은 변경 가능성이 높다. 회사의 기본 할인 정책을 아직 정하지 못했고, 오픈 직전까지 고민을 미루고 싶다. 최악의 경우 할인을 적용하지 않을 수도 있다. (미확정)

이러한 상황에서 도메인 설계에 필요한 것은,
역할과 구현 이다.

할인 정책이 언제든지 변경 가능해야 하기 때문에(바꿔 껴야하기 때문에) 할인 정책 이라는 인터페이스(역할)을 만들고 이것의 구현체를 만들어 유연하게 설계한다.

위의 요구사항을 보면, 회원의 등급에 대해 할인 정책이 정해진다.
1000원이라는 정해진 가격이 할인되는 정책을 위해서는 '정액 할인 정책' 구현체를, 가격에 따라 할인 금액이 변동되는 정책을 위해서는 '정률 할인 정책'이라는 구현체를 만들어 둘 수 있다.

💡 그럼 할인 정책의 인터페이스(역할)에는 무엇이 들어가야 할까?

할인 기준인 회원 등급에 따라 할인 정책이 정액이든 정률이든 실행된다.
따라서 할인 정책의 인터페이스에는 Member와 price를 파라미터로 받고 할인된 가격을 return 하는 메소드가 있으면 된다.
이 메소드는 당연히 정액 할인 정책 구현체(FixDiscountPolicy)와 정률 할인 정책 구현체(RateDiscountPolicy)에서 각각의 할인 방식에 맞게 바꾸어 구현해야 한다.

< DiscountPolicy > 인터페이스(=역할)

public interface DiscountPolicy {
 /**
 * @return 할인 대상 금액
 */
 int discount(Member member, int price);
}

< FixDiscountPolicy > 구현체

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

⭐⭐할인 기준이 변경된다면?⭐⭐

기존의 할인 기준 : 회원 등급에 따라 할인(BASIC, VIP)
변경된 할인 기준 : 특정 상품들만 할인

위에서 할인 정책 인터페이스(역할)에 discount 메소드로 Member와 price를 파라미터로 받고 있다.
하지만!! 변경된 할인 기준에 따르면 할인 금액을 구하기 위해 더이상 Member는 필요 없고(회원 등급이 필요 없기 때문) Item의 정보가 필요하다.

즉, 할인 정책이라는 가정 자체가 변경되었다!!

-> 할인 정책 인터페이스부터 전체적인 설계를 다시 진행해야 할까?
-> 아니다! 사실 이의 경우는 변경이라기 보다 할인 정책 추가이다. 할인 정책에 대한 부분들이 다른 부분들과 잘 분리가 되어있다면 설계를 뒤엎지 않아도 된다.

현재의 DiscountPolicy 인터페이스는 Item을 받아들일 수 없는 구조로 설계되어 있다.

public interface DiscountPolicy {
	int discount (Member member, int price);

위의 코드에서 제네릭을 활용하여 유연하게 변경해보자!!

public interface DiscountPolicy<T> {
	int discount (T condition, int price);

여기서 T는 Type을 말한다.

👍 이제 DiscountPolicy의 구현체를 만들 때 implements DiscountPolicy< Member >로 작성하거나, implements DiscountPolicy< Item >으로 작성하여 discount 메서드를 구현할 때 파라미터로 Member 혹은 Item을 받을 수 있게 된다.
예를 들어 이런 식으로..

  • 예시 1 : FixDiscountPolicy 구현체는 회원 등급을 사용하여 할인을 결정하는 구현체이다.
public class FixDiscountPolicy implements DiscountPolicy<Member> {
	
    @Override
    public int discount(Member condition, int price) {
    	return 0;
    }
}
  • 예시 2 : ItemDiscountPolicy 구현체는 상품 정보를 사용하여 할인을 결정하는 구현체이다.
public class ItemDiscountPolicy implements DiscountPolicy<Item> {

    @Override
    public int discount(Item condition, int price) {
        return 0;
    }
}

출처

  • 인프런 스프링 핵심 원리 - 새로운 할인 정책 개발 - 질문게시글

0개의 댓글