포인트 시스템

dongdong·2023년 1월 2일
0

공부프로젝트

목록 보기
2/9

1. 요구사항


  • 주문시 최종 결제 금액의 1% Point 적립
  • 적립된 Point는 다음 결제시 사용 가능
  • 만료일이 지난 경우 Point 사용 불가
  • 현재있는 쿠폰시스템과 중복 할인이 가능해야 한다.
  • 언제 적립과 사용 되었는지 알 수 있는 history 구현
  • 포인트 사용할시 포인트 적립 x

2. 구조

주문 금액을 계산하기위해 DiscountPolicy인터페이스에 의존한다. 이렇게 하면 실행 시점에 금액을 계산 할 수 있게 된다.

addtionalDiscountPolicy


다른 할인과 조합될 수 있게 DiscountPolicy타입의 next라는 인스턴스 변수를 포함한다. calculatePrice()는 next인스턴스에게 먼저 가격을 계산하게 한 후 추가 할인을 적용하기 위해 afterCalculated메서드를 호출한다. addtionalDiscountPolicy를 상속 받은 자식클래스는 afterCalculated()를 적절히 구현해준다.

3. 설계

  • Point
    - id
    - 고객id
    - 금액
    - 타입
    - 거래일자
    - 만료일자
    - 남은포인트
    - 상태(적립 or 사용)

  • Point_history
    - id
    - 고객id
    - 거래포인트
    - 타입
    - 처리일자
    - 만료일자
    - 상태(적립 or 사용)


    4. 엔티티

Point.java

Point엔티티

PointHistory.java

두 엔티티 모두 JPA Auditing 기능을 사용하였고, Point엔티티의 경우 Point를 저장할때 history를 남기기 위해 PointEntityListener를 만들었다.

PointEntityListener


주석 부분에 어떤 코드가 들어가야할지 고민 했다.
요구사항을 보면 포인트를 사용할 경우 먼저 적립된 포인트부터 순차적으로 사용되어야 한다.

ex) history에 다음과 같이 있다면,
적립(100), 사용(-10), 적립(100)
사용(-10)은 맨 앞에 적립(100 + -10) = 90 이고 이때 150포인트를 사용하려 한다면 히스토리는 다음과 같아야한다.
사용(-150)은 앞서 사용되고 남은 90을 먼저 사용처리 해야한다.즉, history에는 -90, -60 이 되어야 한다.

✅구현하기 위해 내가 생각한 방법은 에서 유저의 pointhistory에서 사용(-) 포인트와 적립(+) 포인트를 따로 구한 후 먼저 적립된 포인트 부터 차례대로 사용 포인트와 더해서 현재 남은 포인트를 구한다음 history에 남기는걸로 했다.

PointEntityListener의 prePersistAndPreUpdate메서드 중간부분 (전체 코드는 깃에 올려두었다.)

사용할 포인트 + 앞에 남은 포인트 했을때 0보다 작다는 것은 앞에 남은 포인트보다 사용할 포인트가 더 크기 때문에 앞에 남은 포인트를 전부 사용 처리해서 history에 남긴다.
0보다 크다는 것은 위의 (100 + -10)처럼 사용포인트가 앞에 남은 포인트보다 작다는의미이기 때문에 사용포인트를 history에 남긴다.

ApplicationEventPublisher

포인트를 사용해서 가격을 계산하고, 주문 후에 포인트가 적립되는것은 orderService에서 일어난다.
orderService에 과하게 의존하는것을 줄이기 위해 EventPublisher를 사용했다.

@EventListener 어노테이션으로 리스너를 등록하고,
등록된 리스너가 이벤트가 발생 했을때 해당 이벤트를 처리 해준다.

orderService에서 ApplicationEventPublisher를 주입받고, 아래와 같이 이벤트를 발생 시켜주면된다.

profile
공부하고 기록하기~

0개의 댓글