티스토리 뷰

반응형

EnumSet을 사용하는 방법 

EnumSet은 다른 컬렉션들과 다르게 new 연산자 사용이 불가능합니다. EnumSet은 아래와 같은 방법으로 사용합니다.

//DayOfWeek라는 Enum을 다루는 Set으로 비어있는 Set을 반환
EnumSet enumSet1 = EnumSet.noneOf(DayOfWeek.class);

//모든 DayOfWeek Enum의 값을 담고있는 Set을 반환
EnumSet enumSet2 = EnumSet.allOf(DayOfWeek.class);

정적 팩토리 메소드(static factory method)만으로 EnumSet의 구현 객체를 반환받을 수 있습니다. 왜 이렇게 만든 걸까요?

 

EnumSet 내부를 살펴보자

(아래 코드는 설명을 위해서 간소화한 코드입니다.)

public abstract class EnumSet { //EnumSet은 abstract하여 객체 생성이 불가능하다.
    ...
    
    //noneOf 메소드에서 상황에 따라 다른 구현체 객체들을 만들어서 반환해주고 있다.
    public static noneOf(...) {
        if (enumElementSize <= 64)
            return new RegularEnumSet<>(...);  
        else
            return new JumboEnumSet<>(...);
    }
}

기본적으로 EnumSet은 abstract 키워드가 사용되기 때문에 객체로써 생성 및 사용이 불가능합니다.

 

그리고 EnumSet의 구현 객체를 반환 받을 때 사용한 noneOf 메소드를 살펴보면 내부적으로 EnumSet을 상속받은 RegularEnumSetJumboEnumSet을 생성하고 반환해 주고 있습니다. (상속받은 두개의 클래스 역시 생성자가 public 하지 않아, 사용자가 임의로 생성하여 사용할 수 없는 구조 입니다.)

 

왜 이렇게 만들었을까?

1. 사용자 편의성 - (사용자는 어떤 구현 객체가 적합한지 몰라도 상관없다)

RegularEnumSet은 원소의 갯수가 적을 때 적합하고, JumboEnumSet은 원소의 갯수가 많을때 적합하지만, 이는 EnumSet의 구현체들을 모두 알고 있는 사용자가 아니라면 난해한 선택지가 될 수도 있습니다. 하지만 EnumSet을 가장 잘 알고 있는 EnumSet 개발자가 적절한 구현 객체를 반환해준다면 EnumSet을 사용하는 입장에서는 어떤 구현체가 적합한지 고려하지 않아도 됩니다.

 

2. 사용자 편의성2 - (사용자는 빈번하게 발생되는 EnumSet초기화 과정을 간단히 진행할 수 있다.)

EnumSet이 다루는 Enum의 모든 원소들을 Set에 담는 행위는 빈번하게 수행될 것으로 예상되는 일입니다. 이러한 경우를 대비하여서 EnumSet의 allOf라는 메소드를 사용하면 모든 Enum 원소가 담겨있는 EnumSet을 쉽게 반환받고 사용 할 수 있습니다. 

 

3. EnumSet의 확장성과 유지보수의 이점

EnumSet을 유지보수하는 과정에서 RegularEnumSet과 JumboEnumSet 이외에 다른 경우를 대비하는 구현 클래스가 추가 된다고 하여도 내부에 감추어져 있기 때문에, EnumSet을 사용하던 기존의 코드에는 전혀 영향이 없습니다. 심지어 RegularEnumSet이 삭제된다 하더라도 사용자에게 영향이 없습니다. 이는 EnumSet의 확장성의 큰 이점으로 작용할 수 있습니다.

 


참고자료

https://javarevisited.blogspot.com/2014/03/how-to-use-enumset-in-java-with-example.html

- 이펙티브 자바 - 조슈아 블로크 저

 

반응형
댓글