본문 바로가기
개발잡담

글로만 배웠던 Enum 을 활용해보자

by 행복한집사 2021. 10. 17.

어떤 달의 첫 시작일의 요일이 주어지면 그 달의 첫번째 토요일, 일요일이 몇 일인지 계산해야 할 일이 있었다.

처음에는 아래처럼 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

https://techblog.woowahan.com/2527/

댓글