java - ENUM(상태와 행위를 한곳에서 관리)
Java Enum 활용기 참고하여 작성되었습니다.
자바 이넘
자비 enum 을 활용하면 상태와 행위를 한곳에서 관리할 수 있는 장점에 대해서 알아 보겠습니다.
예시로 로또 상금 로직 구현해보면서 파악해보겠습니다. 우선 Enum 미적용된 코드부터 살펴 보겠습니다.
Enum 으로 적용안되었을 경우
class LottoRank {
private final static Long FIRST_PRIZE = 1000000L;
private final static Long SECOND_PRIZE = 80000L;
private final static Long THIRD_PRIZE = 5000L;
private final static Long NONE_PRIZE = 0L;
private final static int MATCHED_COUNT_FIRST = 6;
private final static int MATCHED_COUNT_SECOND = 5;
private final static int MATCHED_COUNT_THIRD = 4;
public Long getPrize(int matchedCount) {
switch (matchedCount) {
case MATCHED_COUNT_FIRST :
return FIRST_PRIZE;
case MATCHED_COUNT_SECOND :
return SECOND_PRIZE;
case MATCHED_COUNT_THIRD :
return THIRD_PRIZE;
}
return 0L;
}
}
LottoRank
클래스는 맞춘 로또 숫자에 따라 상금을 반환해주는 getPrize
메소드를 가지고 있습니다.
# 테스트 코드
LottoRank lottoRank = new LottoRank();
int matchedCount = 6;
Long prize = lottoRank.getPrize(matchedCount);
System.out.println(prize); // 6개 일치이므로 1000000 이 출력됩니다.
우선 위 코드는 확장성에 취약한 상태입니다.
만약에 4등의 상금이 줘야하는 추가 요구상황이 주어졌다면 어떻게 될까요?
...
# 추가
private final static Long FOURTH_PRIZE = 1000L;
...
public Long getPrize(int matchedCount) {
switch (matchedCount) {
case MATCHED_COUNT_FIRST :
return FIRST_PRIZE;
case MATCHED_COUNT_SECOND :
return SECOND_PRIZE;
case MATCHED_COUNT_THIRD :
return THIRD_PRIZE;
# 추가
case MATCHED_COUNT_FOURTH :
return FOURTH_PRIZE;
}
return 0L;
}
이처럼 상태와 로직을 각각 수정해주어야 합니다.
LottoRank
클래스의 인스턴스 변수와 메소드가 같이 있어서 그나마 나아보일 수도 있지만,
위 예제는 단순한 예제이고 복잡해질 경우 유지보수와 확장성에서 어려움을 격을 수 있습니다.
Enum 을 활용한다면 어떻게 될까요?
enum LottoRankEnum {
FIRST(6, 1_000_000L),
SECOND(5, 80_000L),
THIRD(4, 5_000L),
FOURTH_PRIZE(3, 1_000L),
NONE(0, 0L);
public int matchedCount; // 당첨된 로또 갯수
public long prize; // 상금
LottoRankEnum(int matchedCount, Long prize) {
this.matchedCount = matchedCount;
this.prize = prize;
}
public static LottoRankEnum valueOf(int matchedCount) {
return Arrays.stream(values())
.filter(lottoRankEnum -> lottoRankEnum.matchedCount == matchedCount)
.findFirst().orElse(NONE);
}
}
테스트 코드
@Test
void LottoRankEnumTest() {
LottoRankEnum lottoRankEnum = LottoRankEnum.valueOf(6);
System.out.println(lottoRankEnum.prize); // 출력 : 1000000
}
위 Enum 에도 4등이 빠져 있습니다. 4등을 추가 해주고 싶다면
FOURTH_PRIZE(3, 1_000L),
위 코드만 추가해주면 확장 할 수 있습니다. 이는 상태와 로직이 하나로 정의 되어 있으므로 한번에 관리될수 있는 장점이 있습니다.
또한 처음 클래스로 만들었던 코드에서는
FIRST_PRIZE = 1000000L
, MATCHED_COUNT_FIRST = 6
연관이 있지만, 서로의 연관성은 로직을 보지 않는다면 알기가 힘듭니다.
이는 프로젝트가 커지면 실수로 이어질수 있는부분이라고 생각됩니다.
Enum
객체에서는 FIRST(6, 1_000_000L)
이처럼 두 상태가 같이 움직이게 되므로 연관이 있다는걸 바로 알수있습니다.
또한, 상태와 로직이 같이 움직이므로 확장성과 유지,보수에서 많은 장점이 있어보입니다.