- 상수 목록을 담을 수 있는 데이터 타입
- 특정한 변수가 가질 수 있는 값을 제한 가능. Type-Safety를 보장 할 수 있다.
- 싱글톤 패턴을 구현할 때 사용하기도 한다.
- 문자열과 비교해 IDE의 폭넓은 지원을 받을 수 있다. ( 자동완성, 오타검증 등)
- 리팩토링 시 변경 범위 최소화
java의 Enum은 코드의 가독성을 생각하며 만든 기능을 갖춘 클래스이기 때문에 여러가지 장점이 있다.
1. 데이터들의 연관관계 표현
특정 값을 이용해 또다른 값을 만들어내야 하는 상황은 많이 발생한다.
public String getTypeFromValue(String value){
if( "a".equals(value) ){
return "aaa";
}
else if( "b".equals(value) ) {
return "bbb";
}
...
...
...
}
boolean, string, int 등 어느 값을 이용하든 정상동작하도록 만들어낼 수 는 있지만
비교해야하는 값, 코드의 양이 늘어날 수록 if문의 반복적인 사용으로 가독성이 저하되고 실수의 여지가 늘어나게 된다.
이런 부분을 Enum을 이용해 추출할 수 있다.
@Getter
public enum Resolutions{
P144("144",176,144),
P240("240",320,240),
P480("480",640,480),
P720("720",1280,720),
P1080("1080",1920,1080),
;
private final String progressive;
private final int width;
private final int height;
Resolutions(String progressive, int width, int height) {
this.progressive = progressive;
this.width = width;
this.height = height;
}
private static final Map<String, Resolutions> descriptions =
Collections.unmodifiableMap(Stream.of(values())
.collect(Collectors.toMap(Resolutions::getProgressive, Function.identity())));
public static Resolutions findSizeByProgressive(String progressive) {
return Optional.ofNullable(descriptions.get(progressive))
.orElse(null);
}
}
어떠한 영상을 재생할 때 해상도를 직접 선택할 수 있다고 하자.
기존 해상도를 받는 코드는 String값인 "240", "480"등을 받아 switch case를 이용해서 width과 height를 반환하도록 했었다.
예제는 5개 정도의 enum 밖에 없지만 실제 프로젝트 코드에서는 몇백개 이상의 enum이 한 코드에 들어있기도 했다.
이런 if문이나 switch case와 같이 반복되는 부분은 최대한 없애는 것이 좋다며 선임이 조언을 해줬는데
생각 이상으로 코드가 정말 간결해져서 앞으로도 자주 활용해야 겠다고 다짐했다.
각 해상도는 progressive, width, height라는 속성을 가지고 있다.
findSizeByProgressive라는 정적 메서드를 포함하고 있고,
이 메서드는 progressive 값을 입력으로 받아 해당하는 해상도를 반환한다.
만약 입력된 progressive 값에 해당하는 해상도가 없을 경우 null을 반환한다.
예를 들어, Resolutions.findSizeByProgressive("720")를 호출하면 P720라는 해상도가 반환된다.
또한, Resolutions 열거형은 descriptions라는 Map을 사용하여 progressive 값을 key로 해당하는 해상도를 value 가지고 있다.
이를 통해 특정 progressive 값을 가지는 해상도를 빠르게 찾을 수 있다.
Collections.unmodifiableMap() 메서드는 변경할 수 없는 읽기 전용 Map을 생성한다.
Stream.of(values())를 사용하여 Enum 클래스에 정의된 모든 값들을 스트림으로 생성합니다.
이후 Collectors.toMap(Resolutions::getProgressive, Function.identity())를 사용하여 progressive 값을 키(key)로,
해당 Resolutions 값을 값(value)으로 가지는 Map을 생성한다.
즉, Resolutions 열거형의 모든 값들을 progressive 값을 기준으로 매핑한 Map을 생성하고, 이를 Collections.unmodifiableMap()으로 변경할 수 없는 읽기 전용 Map으로 만든다.
이를 descriptions라는 변수에 할당하여 Resolutions.findSizeByProgressive() 메서드에서 사용한다.
//생성자의 일부분
Resolutions resolutions = Resolutions.findSizeByProgressive( String value );
this.resolution = new Size(resolutions.getWidth(),resolutions.getHeight());
기존 5개의 switch case로 구성되어 있던 부분이 이렇게 수정되었다.
또, 위 코드에서 findSizeByProgressive와 같은 메서드 외에도 다른 행위들을 한 곳에서 관리 할 수 있다.
위의 해상도를 이용해 비교를 하던, 무언가를 생성하던 어떠한 행위를 하는 메서드들을 한 클래스에 모아놓을 수 있다.
데이터들의 그룹 관리에도 사용 할 수 있고 이렇게 되면 데이터의 관리 주체를 클래스나 메서드로 확장하지 않고 객체로만 유지 할 수 있다.
이 외에도 열거타입은 많은 활용 방법이 있다.
앞으로도 코드의 간결화와 생산성을 위해 자주 활용해보려고 한다.
'JAVA > 자바' 카테고리의 다른 글
[Java] 해시 알고리즘이란? (0) | 2023.06.30 |
---|---|
함수형 인터페이스 (0) | 2023.06.10 |
[JAVA] SOLID 객체지향 설계 5원칙 (2) | 2022.02.26 |
[JAVA] Static과 Final (0) | 2022.02.26 |
[JAVA] 스택과 힙 , 가비지 컬렉터 (1) | 2022.02.25 |