2022. 9. 19. 20:09ㆍDev/Java
enum으로 할 수 있는 다양한 활용이 있는데 단순히 상수를 정의 하는 것만으로 끝내기에는 너무 아쉽다. 다양한 활용법 중에서 이 글에서는 가장 먼저 각 상수가 데이터-value를 가지도록 작성하는 방법과 이것이 활용적인 측면에서 가지는 이점에 대해서 알아보고자 한다.
Value 의 추가
하나의 상수에 하나의 값을 연관지어보자. 예를 들면 "월요일 점심은 도시락, "화요일 점심은 고구마"...
A이면 B의 가장 단순한 폼은 조건문(if-else / swith-case)일 것이다. 이를 코드로 보면
public String getLunchMenuByDayOfWeek(DayOfWeek dayOfWeek) {
String menu;
if (dayOfWeek == DayOfWeek.MONDAY) {
menu = "도시락";
} else if (dayOfWeek == DayOfWeek.TUESDAY) {
menu = "고구마";
/*
...
else if 수,목,금,토,일 에 대한 추가 정의
...
*/
} else {
menu = "김밥천국";
}
return menu;
}
이러한 코드가 잘못 되었다고 얘기하려는게 아니다. 다만 menu value 가 DayOfWeek 라는 enum 의 상수에 강력하게 묶여 있다면 묶여 있는 것들끼리 한곳에서 관리하도록 작성하는게 더 나은 방법이 될 것이다. 이를 enum 에서는 아래와 같이 작성할 수가 있다.
public enum DayOfWeek {
MONDAY("도시락"),
TUESDAY("고구마"),
WEDNESDAY("도시락"),
THURSDAY("햄버거"),
FRIDAY("샐러드"),
SATURDAY("햄버거"),
SUNDAY("샐러드");
private final String lunchMenu;
DayOfWeek(String lunchMenu) {
this.lunchMenu = lunchMenu;
}
public String getLunchMenu() {
return lunchMenu;
}
}
상수에 넣을 데이터의 형을 instant field 로 선언하고 enum상수에 전달될 문자열 lunchMenu는 immutable 이므로 final 로 선언한다. 선언한 field가 초기화 될 수 있도록 생성자를 작성하고, 마지막으로 상수에 해당하는 메뉴를 추출할 getter 를 만들어 준다. 이 중에서 final instant field와 생성자는 필수이고 getter는 옵션이다.(이 예제에서는 넣었지만 필요 없다면 작성하지 않아도 된다. 즉 다른 method 들을 추가할 수도 있다)
이제 "상수:점심메뉴"가 완벽하게 하나로 묶였다.
조금 더 확장해보자
public enum DayOfWeek {
MONDAY("빵","도시락", "샐러드"),
TUESDAY("빵","고구마", "고기"),
WEDNESDAY("미역국", "도시락", "샐러드"),
THURSDAY("샐러드", "햄버거", "카레"),
FRIDAY("카레","샐러드", "고기"),
SATURDAY(null, "햄버거", "피자"),
SUNDAY(null, "샐러드", "치킨");
private final String breakfastMenu;
private final String lunchMenu;
private final String dinnerMenu;
DayOfWeek(String breakfastMenu, String lunchMenu, String dinnerMenu) {
this.breakfastMenu = breakfastMenu;
this.lunchMenu = lunchMenu;
this.dinnerMenu = dinnerMenu;
}
// 이하 getter
}
위에서 예시로 든 if-else 문으로 위의 enum을 역으로 대체한다고 생각해보자. 얼마나 코드가 산만해질지 예상이 갈 것이다.(하나의 method로 아침/점심/저녁 메뉴 3개를 리턴받기 위해서는 리턴타입을 별도로 정의해줘야 하거나 아침/점심/저녁 메뉴를 리턴하는 3개의 method 를 작성해야 할 것이다)
이것과 닮아 있다?
이렇게 강력하게 상수와 묶여 있는 value 들을 보면 마치 관계형 데이터베이스의 테이블의 구조와 닮아 있다. 위의 enum을 table model 로 나타내면 아래와 같다.
breakfastMenu | lunchMenu | dinnerMenu | |
MONDAY | "빵" | "도시락" | "샐러드" |
TUESDAY | "빵" | "고구마" | "고기" |
WEDNESDAY | "미역국" | "도시락" | "샐러드" |
THURSDAY | "샐러드" | "햄버거" | "카레" |
FRIDAY | "카레" | "샐러드" | "고기" |
SATURDAY | null | "햄버거" | "피자" |
SUNDAY | null | "샐러드" | "치킨" |
enum의 상수:values 구조가 행:열의 2차원 구조로 되어 있고 관계형 데이터베이스의 데이터들 또한 이렇게 구성되어 있기 때문에 서로 닮아 있다.
활용
데이터베이스의 테이블 중에 runtime 중 절대로 변하지 않는 value를 가진 테이블이 있다면 enum으로 대체할 수 있을 것이다. 데이터베이스를 사용하는 cost 를 절약할 수도 있고 형상관리툴을 사용한다면 상수와 values 의 생성/변경/삭제 등의 이력을 관리하기에도 용이할 것이다.
'Dev > Java' 카테고리의 다른 글
[short-note] Spring Webflux: Webclient SOCKS5 Proxy setting with Auth(ID/PW) (0) | 2023.02.06 |
---|---|
조건이 복잡한 IF/ELSE-IF 문 리팩토링 (1) | 2023.01.06 |
[Spring] 같은 계층의 N개의 의존성 리팩토링 (0) | 2022.10.11 |
enum 의 활용(2) - method 추가 (0) | 2022.09.22 |
상수의 정의 (1) | 2022.09.09 |