반응형
싱글턴: 인스턴스를 오직 하나만 생성할 수 있는 클래스
주의점: 클래스를 싱글턴으로 만들게 되면 사용하는 클라이언트를 테스트하기가 어려워진다. ->MOCK객체를 만들 수 없기 때문에
<싱글턴을 만드는 방식>
1. public static final 방식의 싱글턴
public static final Elvis INSTANCE = new Elvis();
private Elvis(){...}
위 코드처럼 INSTANCE를 호출하게 되면 Elvis는 최초 한 번만 만들어진 이후에 쭉 재사용된다.
장점: public static final 클래스이므로 맨 처음에 메모리가 올라오고 나서 변경이 불가능하니 명백히 싱글턴임이 드러난다.
Elvis el = new Elvis(); //불가능
Elvis el1 = Elvis.INSTANCE; //가능
Elvis el2 = Elvis.INSTANCE; //가능 ->el1과 el2는 같은 객체를 참조하고 있는 상태
단점: 권한이 있는 사용자가 리플렉션 API의 setAccessible()을 통해 private 생성자를 호출하여 객체를 중복하여 만들 수 있다. (공격)
이러한 경우를 방지하기 위해서 생성자를 수정하여야한다. -> 두 번째 객체가 생성될 때 예외를 던지도록 수정
2. 정적 팩터리 방식의 싱글턴
private static final Elvis INSTANCE = new Elvis();
private Elvis(){...}
public static Elvis getInstance(){ return INSTANCE; }
Elvis.getInstance는 항상 같은 객체의 참조를 반환하므로 Elvis의 인스턴스는 결코 만들어지지 않는다.
Elvis el = Elvis.getInstance();
3. 열거 타입 방식의 싱글턴
public enum Elvis{
INSTANCE;
public String getName(){
return "yuna";
}
}
더 간결하고 아주 복잡한 상황이나 공격에도 제2의 인스턴스가 생기는 일을 완벽히 막아준다.
대부분의 상황에서는원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.
String name = Elvis.INSTANCE.getName();
반응형
'Effective Java' 카테고리의 다른 글
[아이템4] 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2023.04.27 |
---|---|
[아이템2] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2023.04.27 |
[아이템1] 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.04.27 |