Item38
확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라
1 개요
- 열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수하다
- 단, 예외가 하나 있으니, 타입 안전 열거 패턴은 확장이 가능하나 열거 타입은 확장이 불가능하다
- 타입 안전 열거 패턴은 열거한 값을 그대로 가져온 다음 값을 더 추가하여 다른 목적으로 쓸 수 있다
- 하지만 열거 타입은 의도적으로 확장이 불가능하게 설계되었다
- 열거 타입 확장이 필요한 경우 인터페이스와 그 인터페이스를 구현하는 기본 열거 타입을 함께 사용해 확장 효과를 낼 수 있다.
1.1 타입 안전 열거 패턴
- enum이 도입되기 전(JDK 1.5 이전)에 사용하던 방식으로 제한된 수의 정적 타입을 만들어놓고 사용하는 패턴을 말한다.
- 정수 열거 패턴의 단점을 해결하고자 제안되었다.
- Item34.md 정수 열거 패턴 참고
- 참고로 자바 이펙티브 초판에 기술된 내용이다.
정수 열거 패턴
- 타입 안전성이 없다
public class AppleV1 {
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
}
public class OrangeV1 {
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;
}
@Test
void test() {
assertThat(AppleV1.APPLE_FUJI).isEqualTo(OrangeV1.ORANGE_NAVEL);
}
타입 안전 열거 패턴
- 타입 안전성이 있다
- 열거 타입은 상수 하나당 자신의 인스턴스를 하나씩 만들어 public static final 필드로 공개하는데 열거 타입이 존재하기전 같은 방식으로 타입 안전 열거 패턴을 사용했다
public class AppleV2 {
private final String name;
public static final AppleV2 FUJI = new AppleV2("fuji");
public static final AppleV2 PIPPIN = new AppleV2("pippin");
public static final AppleV2 GRANNY_SMITH = new AppleV2("granny smith");
public AppleV2(String name) {
this.name = name;
}
}
public class OrangeV2 {
private final String name;
public static final OrangeV2 NAVEL = new OrangeV2("navel");
public static final OrangeV2 TEMPLE = new OrangeV2("temple");
public static final OrangeV2 BLOOD = new OrangeV2("blood");
public OrangeV2(String name) {
this.name = name;
}
}
@Test
void test() {
assertThat(AppleV2.FUJI).isNotEqualTo(OrangeV2.NAVEL);
}