Item 3. private, enum을 사용한 싱글턴

심규환·2022년 1월 9일
0

Effective Java

목록 보기
3/29
post-thumbnail

싱글턴 패턴(Singleton pattern)이란?

싱글턴 패턴이란, 한 클래스에 하나의 인스턴스만을 보장하는 패턴이다. 그러면 하나의 인스턴스만 사용하는 것이 어떤점이 좋을까?
먼저 첫 번째로 메모리 절약이 가능하다는 점이다. 하나의 인스턴스를 생성하면 반복적으로 호출해도 따로 생성없이 만들어 놓은 인스턴스만을 가져오기 때문에 메모리가 절약되며 속도도 향상 된다.
두 번째는 클래스간 자원 공유가 가능하다는 점이다. public을 통한 전역적 선언으로 어디서든 이 인스턴스를 사용할 수 있다.

그럼 싱글턴 패턴의 단점은 무엇일까?
테스트 하기가 어렵다. 하나의 인스턴스로 여러 클래스에 공유하기 때문에 따로 테스트 하기가 어렵다.
또 다중 스레드 환경의 경우, 동시성 문제가 발생할 수 있게 된다. 이를 해결하기 위해 하나의 스레드만 사용이 허용하도록 syncronized를 사용하면 된다.

자 그러면 싱글턴임을 보증하는 방법을 설명하겠다. 대표적인 방법으로는 세 가지가 있다.

1. public static final 필드 방식의 싱글턴

public class Singleton{
	public static final Singleton INSTANCE = new Singleton();
    private Singleton(){} // 생성자를 private로 막기
    
    public void ...
}

private 생성자는 public static final 필드인 Singleton.INSTANCE를 초기화할 때, 딱 한번만 호출된다.
이 밖에 다른 생성자는 없기 때문에 하나의 인스턴스임을 보증한다.

이 방식의 이점으로는 public 필드를 사용하여 해당 클래스가 싱글턴임을 API에 명백히 드러난다는 점이다.
또 한 줄로 간단하게 작성할 수 있다는 장점이 있다.

2. 정적 팩터리 방식의 싱글턴

public class Singleton {
	private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() { return INSTANCE; }
    
    public void ...
}

다음은 정적 팩터리를 사용한 방식이다. 정적 팩터리를 사용한 이점은 세 가지가 있는데. 자세한 설명은 뒤에 적어 놓은 아이템을 배우고 나서 수정하겠다.

1) API를 바꾸지 않아도 싱글톤이 아니게 변경 가능
2) 정적 팩터리를 제네릭 싱글 팩터리로 변경 가능(item 30)
3) 정적 팩터리의 메소드 참조를 공급자로 사용할 수 있다.(item 43, 44)

위에 세 가지의 장점을 사용하지 않는다면 public 필드 방식을 사용하는 것이 좋다.

3. 열거 타입 방식의 싱글턴 - 바람직한 방법

public enum Singleton {
	INSTANCE;
    
    public void ...{ }
}

public 필드 방식과 비슷하지만, 더 간결하고, 추가 노력 없이 직렬화할 수 있고, 심지어 아주 복잡한 직렬화 상황이나 리플렉션 공격에도 제2의 인스턴스가 생기는 것을 완벽히 막아준다.(생성자 자체가 없기 때문)

대부분 상황에서는 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.

profile
장생농씬가?

0개의 댓글