싱글턴
•
싱글턴(singleton)이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다.
•
클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트는 테스트하기가 어려워질 수 있다.
싱글턴 클래스를 만드는 방법
•
싱글턴을 만드는 방법은 생성자를 private로 감춰두고 public static final 멤버로 해당 인스턴스를 보관하는 방식이 있다.
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
...
}
Java
복사
•
이 방식은 해당 클래스가 싱글턴임이 API에서 명백히 드러나고, 간결하다는 장점이 있다.
•
싱글턴을 만드는 두 번째 방법은 위와 같지만 인스턴스를 보관하는 멤버를 private로 바꾸고, 정적 팩터리 메서드를 제공하는 것이다.
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
...
}
Java
복사
•
이 방식의 장점은 추후 싱글턴을 아니게 바꾸고 싶을 때, API를 변경하지 않고도 간단하게 수정가능하다는 점이다. 또한 원한다면 정적 팩터리를 제네릭 싱글턴 팩터리로 만들 수도 있다. 마지막으로 정적 팩터리의 메서드 참조를 함수형 인터페이스 구현체인 공급자(supplier)로 사용할 수 있다는 것이다.
•
두 방식 모두 시스템에서 해당 클래스가 하나임을 보장할 수 있고, 생성자 내에서 두 번째 호출을 받게 되면 예외를 던지도록 하여 리플렉션을 통해 생성자 호출하는 것까지 막을 수 있다.
•
싱글턴 클래스를 직렬화 하려면, 위 두 방식에서 인스턴스 필드를 transient로 선언하고 readResolve 메서드를 제공해 여러 인스턴스가 생성되는 것을 막아야 한다.
•
싱글턴을 만드는 세 번째 방법은 원소가 하나인 열거 타입을 선언하는 것이다.
public enum Elvis {
INSTANCE;
...
}
Java
복사
•
첫 번째 방식인 public 필드 방식과 비슷하지만, 더 간결하고 추가 노력없이 직렬화할 수 있고 리플렉션 공격에서도 싱글턴이 깨지지 않는다.
•
대부분 상황에서 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.