싱글턴(singleton)은 인스턴스를 오직 하나만 생성할 수 있는 클래스이다. 설계상 유일하게 존재해야 하는 시스템 컴포넌트는 싱글턴으로 구현되어야 하고 무상태 객체(함수 등)도 싱글턴으로 구현할 수 있다.
public static final 필드
Iu를 생성하는 private 생성자는 public static final 필드인 Iu.INSTANCE를 초기화할 때 한 번만 호출된다. public, protected 접근제한자인 다른 생성자가 없으므로 Iu 클래스를 초기화할 때 만들어진 인스턴스가 전체 시스템에서 단 하나뿐임이 보장된다.
public class Iu {
public static final Iu INSTANCE = new Iu();
private Iu() { ... }
public void leaveTheBuilding() { ... }
}
이 방법은 API에 public static 필드가 final임이 명백하게 드러나 싱글턴이라는 것을 쉽게 확인할 수 있고 코드가 간결하다는 장점이 있다.
정적 팩토리 메서드
Iu.getInstance는 항상 같은 객체의 참조를 반환하므로 여전히 Iu는 유일하게 존재한다.
public class Iu {
private static final Iu INSTANCE = new Iu();
private Iu() { ... }
public static Iu getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}
이 방법은 API를 변경하지 않고도 싱글턴이 아니도록 변경할 수 있다. 정적 팩터리 메서드가 내부적으로 다른 인스턴스를 반환하도록 변경할 수 있고 원한다면 제네릭 싱글턴 팩터리로도 만들 수 있다. 마지막으로 정적 팩터리 메서드 참조를 공급자로 사용할 수 있다. 이러한 장점이 필요없다면 간결한 public 필드 방식을 사용하는 것이 낫다.
위 두 방법 중 한 방법을 사용하려면, 싱글턴 클래스 직렬화에 주의해야 한다.
원소가 하나인 열거타입
대부분 상황에서는 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.
이 방법은 간결하고 복잡한 직렬화 상황이나 리플렉션 공격에도 제2의 인스턴스가 생기는 일을 완벽히 막아준다.
public enum Iu {
INSTANCE;
public void leaveTheBuilding() { ... }
}
'Java > 내맘대로 Effective Java' 카테고리의 다른 글
[Item 6] 불필요한 객체 생성을 피하라 (0) | 2022.03.06 |
---|---|
[Item 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2022.03.05 |
[Item 4] 인스턴스화를 막으려면 private 생성자를 사용하라 (0) | 2022.03.03 |
[Item 2] 생성자에 매개변수가 많다면 빌더를 고려해라 (0) | 2022.03.01 |
[Item 1] 생성자 대신 정적 팩토리 메서드를 고려하라 (0) | 2022.03.01 |