어떤 달의 첫 시작일의 요일이 주어지면 그 달의 첫번째 토요일, 일요일이 몇 일인지 계산해야 할 일이 있었다.
처음에는 아래처럼 if else를 사용하여 요일의 경우에 따라 첫번째 토요일, 일요일을 계산해 줬다.
if("MON".equals(day)){
fSat = 6;
fSun = 7;
}else if("TUE".equals(day)){
fSat = 5;
fSun = 6;
}else if("WED".equals(day)){
fSat = 4;
fSun = 5;
}else if("THU".equals(day)){
fSat = 3;
fSun = 4;
}else if("FRI".equals(day)){
fSat = 2;
fSun = 3;
}else if("SAT".equals(day)){
fSat = 1;
fSun = 2;
}else if("SUN".equals(day)){
fSat = 7;
fSun = 1;
}
급해서 일단 위처럼 짰지만 만약 이 코드를 앞으로 계속 보고 유지보수해야 한다면 if else가 너무 많아서 전체 코드를 읽는데 흐름을 방해할 거 같았다. 그래서 마음 먹은 김에 그동안 글로만 배우고 추억속에서 잊힌 Enum의 개념을 다시 한 번 익히고 활용하여 위 코드를 개선해보기로 했다.
Enum이란 서로 관련 있는 상수들의 집합을 정의한 것이라고 할 수 있다.
예를들어 요일 월,화,수,목,금,토,일은 절대 바뀌지 않고 서로 일주일을 이루는 요일이라는 점에서 연관이 있으므로 Enum으로 정의해 줄 만하다.
Enum의 장점은 여러가지이지만(ex. 허용가능한 값들을 제한) 이번에 언급할 장점은 '상태와 행위를 한 곳에서 관리'할 수 있다는 것이다. 그동안 Enum에 대해서 잘 모르면서 꼭 써야하나? 란 생각이 어렴풋이 들었던 이유가 Enum이 이와 같은 역할을 할 수 있는지 몰랐기 때문이다. 그러나 우아한형제들 기술 블로그 덕분에 Enum의 많은 활용방법을 알게 되었다.
일단 개선한 코드는 아래와 같다.
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
String firstDay = "SUN";
Days days = Days.valueOf(firstDay);//인자로 들어온 String과 일치하는 상수 인스턴스를 반환
int firstSat = days.calFirstSat(7);
int firstSun = days.calFirstSun(8);
System.out.println("firstSat: " + firstSat);//7
System.out.println("firstSun: " + firstSun);//1
}
}
enum Days{
MON(value -> value-1) //public static final class MON extends Days{}
,TUE(value -> value-2) //public static final class TUE extends Days{}
,WED(value -> value-3)
,THU(value -> value-4)
,FRI(value -> value-5)
,SAT(value -> value-6)
,SUN(value -> value-7);
private Function<Integer, Integer> expression;
Days(Function<Integer, Integer> expression){ //요일에 따라 다르게 첫번쨰 토요일의 날짜를 계산할 수 있도록 함수를 인자로 넘김
this.expression = expression;
}
public int calFirstSat(int value){
return expression.apply(value)==0? 7:expression.apply(value);
}
public int calFirstSun(int value){
return expression.apply(value);
}
}
Days라는 enum을 선언해주고 안에 MON, TUE, WED ...등의 열거형 변수를 선언해주었다. (예전에는 열거형 변수라는게 잘 이해가 안 갔는데 찾아보니 enum 타입을 상속받은 하위 클래스였다. 예를 들어 MON은 실제로 public static final class MON extends Days{} 이렇게 되어 있을 것이란 뜻이다. )
그리고 enum 생성시에 각 요일의 경우에 따라 다르게 첫번째 토요일, 일요일을 계산할 수 있도록 함수를 넘겨주고 있다.
실제로 사용시에 보면 어떤 요일이 들어오든 아래와 같이 Days에게 첫번째 토요일, 일요일을 계산하게 시킬 수 있다.
훨씬 코드가 간편하고 Days만 보면 첫번째 토요일, 일요일 계산이 어떻게 되는지 알 수 있다.
참고:
https://effectiveprogramming.tistory.com/entry/enum%EC%9D%98-%ED%99%9C%EC%9A%A9%EB%B2%95
https://stackoverflow.com/questions/32354107/how-are-enums-internally-represented-in-java
'개발잡담' 카테고리의 다른 글
PRG(POST-REDIRECT-GET) 패턴 (0) | 2022.01.02 |
---|---|
Transaction은 뭐고 @Transactional은 언제 쓰는 건데? (0) | 2021.12.26 |
SpringBoot JPA 프로젝트 중간 개선 (0) | 2021.09.27 |
Spring은 어떻게 사용자 요청을 받아서 처리할까? (0) | 2021.08.22 |
ERD를 데이터베이스에 적용해보자(Feat. JPA) (0) | 2021.08.08 |
댓글