아이템 3 - 생성자나 열거 타입으로 싱글턴임을 보증하라
JAVA
·
방법1 : private 생성자 + public static final 필드
- 장점
- 간결하고 싱글턴임을 API에 들어낼 수 있다.
- 단점
- 싱글턴을 사용하는 클라이언트 테스트하기 어려워진다.
- 인터페이스를 구현한 싱글턴이 아니라면 mocking이 불가능하기 때
- 리플렉션으로 private 생성자를 호출할 수 있다.
- 막으려면, flag를 줘서 두 번째부터는 예외를 주면 된다.
- 하지만 그러면 간결함이라는 장점을 잃는다.
- 역직렬화를 할 때마다 새로운 인스턴스가 생길 수 있다.
- Instance를 return하는 readResolve를 정의하면 막을 수 있다.
- 하지만 이마저도 간결함을 잃는다.
방법2 : private 생성자 + 정적 팩터리 메서드
- 장점
- API(클라이언트 코드)를 바꾸지 않고도 싱글턴이 아니게 변경할 수 있다.
- 정적 팩터리를 제네릭 싱글턴 팩터리로 만들 수 있다.
- 같은 인스턴스를 다른 타입으로 사용할 수 있다.
- 정적 팩터리 메서드 참조를 공급자(Supplier)로 사용할 수 있다.
- 인스턴스를 반환하는 정적 팩터리 메서드를 메서드 참조할 수 있음
- 단점은 방법1과 같다.
방법3 : 열거 타입
- 가장 간결한 방법으로 직렬화와 리플렉션에도 안전하다.
- 대부분의 상황에서는 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법
방법4 : 스프링을 사용해라
- 스프링에서 빈으로 등록하면 스프링이 알아서 싱글톤으로 관리
출처
이펙티브 자바 3/E
이펙티브 자바 완벽 공략 1