Java/Effective Java
[아이템 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라
setung
2021. 9. 30. 15:53
싱글톤(singleton)이란 인스턴스를 하나만 생성할 수 있는 클래스를 말한다. 책에서 소개하는 싱글톤 구현 방법을 간단히 보겠다.
1. public static final 필드 방식의 싱글턴
class Elvis_Field {
public static final Elvis_Field INSTANCE = new Elvis_Field();
private Elvis_Field() {
}
}
2. 정적 팩터리 방식의 싱글턴
class Elvis_Method {
private static final Elvis_Method INSTANCE = new Elvis_Method();
private Elvis_Method() {
}
public static Elvis_Method getInstance() {
return INSTANCE;
// return new Elvis_Method(); 싱글톤을 그만 사용하고 싶을 때
}
}
1번과 2번은 싱글톤을 공부할 때 많이 볼 수 있는 패턴이다. private 생성자를 통해 인스턴스를 생성하지 못하게 막는 것이다. 하지만 리플렉션 API를 통해 뚫을 수 있다.
아래는 예시코드다.
private static Elvis_Field getElvis_field() throws InstantiationException, IllegalAccessException, InvocationTargetException {
Class<Elvis_Field> elvis_fieldClass = Elvis_Field.class;
Constructor<?> declaredConstructor = elvis_fieldClass.getDeclaredConstructors()[0];
declaredConstructor.setAccessible(true);
Elvis_Field newElvis_Field = (Elvis_Field)declaredConstructor.newInstance();
return newElvis_Field;
}
3. 열거 타입 방식의 싱글턴
enum Elvis_Enum {
INSTANCE
}
enum을 통해 싱글톤을 구현하는 방법은 여기에서 처음 봤다. 실무에서 많이 사용하는지 모르겠다.
이 외에도 double checked locking 등 싱글톤을 구현하는 다양한 방법이 있다. 하지만 완벽하게 하나의 인스턴스의 생성을 보장하지 못해 안티 패턴으로 알고 있다.
싱글톤 문제점 및 주의
1. private 생성자를 갖는 싱글톤은 상속이 불가하다.
2. 싱글톤은 테스트 환경에서 목 오브젝트 등으로 대체하기 힘들다.
3. 멀티스레드 환경에서 싱글톤이 하나만 만들어지는 것을 보장 못함
4. 상태 정보가 없는 무상태로 만들어야 쓰레드 세이프하다. (읽기 전용 값은 예외)