열거 형 싱글 톤의 일부 문제 :
구현 전략에 전념
일반적으로 "단일"은 API 사양이 아닌 구현 전략을 나타냅니다. Foo1.getInstance()
항상 같은 인스턴스를 반환한다고 공개적으로 선언하는 것은 매우 드 rare니다 . 필요한 경우 Foo1.getInstance()
예를 들어 스레드 당 하나의 인스턴스를 반환 하도록 구현을 발전시킬 수 있습니다.
함께 Foo2.INSTANCE
우리는 공개적으로이 인스턴스가 있음을 선언 예, 그 변화 할 기회가 없습니다. 단일 인스턴스를 갖는 구현 전략이 노출되어 있습니다.
이 문제는 치명적이지 않습니다. 예를 들어 Foo2.INSTANCE.doo()
스레드 당 인스턴스 를 효과적으로 갖기 위해 스레드 로컬 도우미 개체를 사용할 수 있습니다.
열거 형 클래스 확장
Foo2
슈퍼 클래스를 확장합니다 Enum<Foo2>
. 우리는 보통 슈퍼 클래스를 피하고 싶습니다. 특히이 경우, 강제 수퍼 클래스 는 예상되는 Foo2
것과 아무 관련이 없습니다 Foo2
. 이것이 애플리케이션의 유형 계층 구조에 대한 오염입니다. 우리가 정말로 슈퍼 클래스를 원한다면 그것은 보통 응용 프로그램 클래스이지만 Foo2
수퍼 클래스는 고정되어 있습니다.
Foo2
와 같은 재미있는 인스턴스 메소드를 상속합니다.이 메소드 name(), cardinal(), compareTo(Foo2)
는 Foo2
의 사용자에게 혼란을 줍니다. 의 인터페이스 에서 해당 메소드가 바람직하더라도 Foo2
자체 name()
메소드를 가질 수 없습니다 Foo2
.
Foo2
재미있는 정적 메소드도 포함되어 있습니다.
public static Foo2[] values() { ... }
public static Foo2 valueOf(String name) { ... }
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
사용자에게는 무의미한 것으로 보입니다. 싱글 톤은 일반적으로 어쨌든 pulbic 정적 방법이 없어야합니다 (이외의 getInstance()
)
직렬화
싱글 톤이 상태를 유지하는 것은 매우 일반적입니다. 이러한 싱글 톤은 일반적으로 직렬화 할 수 없습니다 . 한 VM에서 다른 VM으로 상태 저장 싱글 톤을 전송하는 것이 의미가있는 현실적인 예는 생각할 수 없습니다. 싱글 톤은 "유니버스에서 고유 한"것이 아니라 "VM 내에서 고유 한"을 의미합니다.
직렬화가 상태 저장 싱글 톤에 실제로 의미가있는 경우 싱글 톤은 동일한 유형의 싱글 톤이 이미 존재할 수있는 다른 VM에서 싱글 톤을 역 직렬화하는 것이 무엇을 의미하는지 명시적이고 정확하게 지정해야합니다.
Foo2
단순한 직렬화 / 직렬화 전략을 자동으로 수행합니다. 그건 그냥 기다리고 사고입니다. Foo2
t1에서 VM1 의 상태 변수를 개념적으로 참조하는 데이터 트리가 직렬화 / 역 직렬화를 통해 값이 다른 값 ( Foo2
t2에서 VM2 의 동일한 변수 값)이되어 버그를 감지하기 어렵습니다. 직렬화 할 수없는이 버그는 Foo1
자동으로 발생하지 않습니다 .
코딩 제한
일반 수업에서는 할 수 있지만 수업에서는 할 수없는 일이 있습니다 enum
. 예를 들어 생성자의 정적 필드에 액세스합니다. 프로그래머는 특별한 수업을하고 있기 때문에 더 조심해야합니다.
결론
열거 형을 피기 백하면 코드 2 줄을 절약 할 수 있습니다. 그러나 가격이 너무 비싸서 열거 형의 모든 수하물과 제한을 수행해야하며 의도하지 않은 결과를 초래하는 열거 형의 "기능"을 실수로 상속합니다. 유일하게 주장되는 장점 인 자동 직렬화 기능은 단점으로 밝혀졌습니다.