금나와라뚝딱(이하 금뚝)의 Event 엔티티는 Ready Running Closed 세가지의 상태를 가질 수 있다. 이벤트는 Ready 상태로 시작해서 이벤트 오픈시간이 되면 Running 상태로 바뀌고 선물 재고가 없거나 종료시간이 되면 Closed 상태로 변경된다. 하지만 분명 Closed된 Event 엔티티가 자꾸 Running 상태로 변경되는 문제가 발생했다.
프로젝트 초기에 이벤트 상태 갱신 방법을 고민했는데, 결과적으로 배치를 이용하는것 대신 Event 엔티티 조회 API를 호출할때 상태를 갱신하도록 정했다. 그래서 renewStatus() 라는 메서드를 작성했다.
처음에 금뚝의 이벤트 종료 조건은 시간만 있었는데 요구사항이 변경되어서 선물 재고 조건도 추가되었다. 하지만 실수로 renewStatus()에 관련 로직 추가를 안해서 문제가 되었다.
그래서 renewStatus() 메서드에 종료 조건을 추가하고 상태 변경이 잘못되지 않도록 로직을 조정함으로써 문제를 해결했다.
초기의 renewStatus 메서드의 모습
public class Event {
private EventProgressStatus eventProgressStatus;
//...
public void renewStatus() {
if (startAt.isAfter(LocalDateTime.now())) {
eventProgressStatus = EventProgressStatus.READY;
return;
}
if (startAt.isEqual(LocalDateTime.now()) || (startAt.isBefore(LocalDateTime.now()) && endAt.isAfter(
LocalDateTime.now()))) {
eventProgressStatus = EventProgressStatus.RUNNING;
return;
}
if (endAt.isEqual(LocalDateTime.now()) || endAt.isBefore(LocalDateTime.now())){
eventProgressStatus = EventProgressStatus.CLOSED;
}
}
}
문제는 임시방편으로 해결했지만 다음과 같은 문제가 남아있다.
그래서 이를 해결하기 위해선 renewStatus()가 가지고 있는 **상태 변경 로직을 분리**하고 **구조적으로 상태간의 변경을 제어**할 수 있는 무언가가 필요했다.
상태패턴의 특징 [참고]