티스토리 뷰

 이번에 준비중인 서비스에서는 서비스 이용 보상으로 스탬프를 준다. 그런데, 그 스탬프 획득 조건이 여러 가지이다. 연속 학습을 했을 때 주는 스탬프도 있고, 특정 날짜에 들어왔을 때 주는 스탬프도 있고. 스탬프 기능을 구현하면서 이걸 JPA로 구현할 때 어떻게 하면 좀 더 객체지향적으로 할 수 있을지 고민했다.

 이런식으로 서비스 이용 보상이 주어지는 경우는 많으니까 다른 분들은 어떻게 하실지 모르겠지만, 나는 아래와 같이 했다.

 우선 스탬프 획득 조건이 크게 세 종류라고 생각하고 진행했다.

  • CountCondition: 어떤 행동을 일정 횟수하면 주어지는 조건
  • TimeRangeCondition: 어떤 기간동안 어떤 행동을 하면 주어지는 조건
  • DateRange: 어떤 날짜에 어떤 행동을 하면 주어지는 조건

 획득 조건이 꼭 학습뿐만이 아니라서 획득 조건은 아래와 같이 구성했다.


  
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "condition_type")
public abstract class StampCondition {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@ManyToOne
protected Stamp stamp;
protected String name;
@Enumerated(EnumType.STRING)
protected ActionType actionType;
@Enumerated(EnumType.STRING)
protected ActionFrequency actionFrequency;
}

 StampCondition을 보면 ActionType과 ActionFrequency가 있다. 이것은 위에서 이야기한 조건의 '어떤 행동'을 '어떻게(반복/연속)'할 것인지에 대한 조건이다.


 좀 더 CountCondition, DateRangeCondition, TimeRangeCondition을 자세히 살펴보면 아래와 같다.


  
@Entity
@DiscriminatorValue("COUNT")
public class CountCondition extends StampCondition {
private int requiredCount;
}

  
@Entity
@DiscriminatorValue("DATE_RANGE")
public class DateRangeCondition extends StampCondition {
private LocalDate startDate;
private LocalDate endDate;
}

  
@Entity
@DiscriminatorValue("TIME_RANGE")
public class TimeRangeCondition extends StampCondition {
int startHour;
int endHour;
}

 모두 StampCondition을 extends하고 있고, 각 조건에 필요한 변수를 가지고 있다. CountCondition을 보자면, ' 어떤 행동을 일정 횟수하면 주어지는 조건'인데 어떤 행동인지는 StampCondition에 정의되어 있으므로, 횟수만 가지고 있다. DateRangeCondition 또한 날짜 범위에 대한 조건이므로 시작일, 종료일을 가지고 있다.


 저렇게 세 가지 종류로 나눠놓았지만 DB로 보면 하나의 테이블이다.(@Inheritance, @DiscriminatorColumn를 사용)

 condition_type에 따라 존재하는 데이터가 다르다. CountCondition은 condition_type이 'COUNT'이고, required_count가 존재하지만, DateRangeCondition은 condition_type이 'DATE_RANGE'이고, start_date, end_date가 존재하는 것이다.

 한 테이블을 JPA에서 구현할 때 굳이 위와 같이 객체로 쪼갤 필요가 있을까 싶을 수도 있는데, 나는 다양한 조건에 따라 필요한 필드가 다르고, 그 필드만 관리하기를 원해서 이런 식으로 구현해보았다.

300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함