티스토리 뷰

donaricano-btn
반응형

이펙티브 자바에서 소개하는 싱글턴을 만드는 방법은 다음 세 가지이다.

 

public class Item3 {

    public static final Item3 INSTANCE = new Item3();

    private Item3() {}

	// ...
    
}

 

첫번째 방법은 생성자를 private 으로 감추고 유일한 인스턴스에 접근할 수 있는 수단으로 public static final 멤버를 하나 만드는 것이다. 생성자는 초기화 할 때 딱 한번만 호출되기 때문에 이 클래스의 인스턴스는 시스템 전체에 하나뿐임을 보증할 수 있다.

 

물론 리플렉션을 통해 생성자를 호출할 수는 있지만 생성자에서 예외를 던지도록 만들어서 방어할 수있다. 이 방법은 싱근턴임을 명확하게 파악할 수 있고 비교적 코드가 간결해 지는 장점이 있다.

 

public class Item3 {

    private static final Item3 INSTANCE = new Item3();

    private Item3() {}

    public static Item3 getInstance() {
        return INSTANCE;
    }
    
    // ...
}

 

두번째 방법은 역시 생성자를 private 으로 감추고 INSTANCE 를 private 으로 숨긴다. 대신 정적 팩터리 메소드를 제공한다. getInscance 메소드는 항상 같은 인스턴스를 반환하기 때문에 역시 인스턴스가 하나뿐임을 보증한다. 리플렉션을 통한 생성은 첫번째 방법과 마찬가지로 막을 수 있다.

 

이 방법은 싱글턴이 아닌 클래스로 변경할 때 이점을 가진다. 또 제네릭을 사용할 수 있다.

 

public class Item3 implements Serializable {

    private static final Item3 INSTANCE = new Item3();

    private Item3() {}

    public Item3 getInstance() {
        return INSTANCE;
    }
    
    // ...
}

 

위 두 방법의 단점은 직렬화를 위해 Serializable 을 구현할 때 발생한다. 직렬화된 인스턴스를 역직렬화할 때 마다 새로운 인스턴스가 만들어지기 때문이다. 이를 방어하기 위해서는 모든 인스턴스필드를 transient 선언하고 readResolve 메서드를 제공해야한다.

 

private Object readResolve() {
    return INSTANCE;
}

 

마지막 방법은 원소가 하나인 열거 타입을 선언하는 것이다.

 

public enum Item3 {
    
    INSTANCE;
    
    // ...
}

 

이 방법을 이용하면 더 간결하고 추가적인 노력 없이 직렬화 할 수 있습니다. 리플렉션에서도 안전하고요. 책에서는 대부분의 경우 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이라고 소개하고 있습니다. 

 

하지만 다른 클래스를 상속해야 한다면 이 방법은 사용할 수 없습니다.

반응형
donaricano-btn
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함