본문 바로가기
Java/Effective Java

[아이템 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라

by setung 2021. 9. 30.

싱글톤(singleton)이란 인스턴스를 하나만 생성할 수 있는 클래스를 말한다. 책에서 소개하는 싱글톤 구현 방법을 간단히 보겠다.

 

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

class Elvis_Field {
    public static final Elvis_Field INSTANCE = new Elvis_Field();

    private Elvis_Field() {
    }
}

 

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

class Elvis_Method {
    private static final Elvis_Method INSTANCE = new Elvis_Method();

    private Elvis_Method() {
    }

    public static Elvis_Method getInstance() {
        return INSTANCE;
        // return new Elvis_Method();   싱글톤을 그만 사용하고 싶을 때
    }
}

 

1번과 2번은 싱글톤을 공부할 때 많이 볼 수 있는 패턴이다. private 생성자를 통해 인스턴스를 생성하지 못하게 막는 것이다. 하지만 리플렉션 API를 통해 뚫을 수 있다.

아래는 예시코드다.

private static Elvis_Field getElvis_field() throws InstantiationException, IllegalAccessException, InvocationTargetException {
        Class<Elvis_Field> elvis_fieldClass = Elvis_Field.class;
        Constructor<?> declaredConstructor = elvis_fieldClass.getDeclaredConstructors()[0];
        declaredConstructor.setAccessible(true);
        Elvis_Field newElvis_Field = (Elvis_Field)declaredConstructor.newInstance();
        return newElvis_Field;
    }

 

3. 열거 타입 방식의 싱글턴

enum Elvis_Enum {
    INSTANCE
}

enum을 통해 싱글톤을 구현하는 방법은 여기에서 처음 봤다. 실무에서 많이 사용하는지 모르겠다.

 

이 외에도 double checked locking 등 싱글톤을 구현하는 다양한 방법이 있다. 하지만 완벽하게 하나의 인스턴스의 생성을 보장하지 못해 안티 패턴으로 알고 있다.

 

싱글톤 문제점 및 주의

1. private 생성자를 갖는 싱글톤은 상속이 불가하다.

2. 싱글톤은 테스트 환경에서 목 오브젝트 등으로 대체하기 힘들다.

3. 멀티스레드 환경에서 싱글톤이 하나만 만들어지는 것을 보장 못함

4. 상태 정보가 없는 무상태로 만들어야 쓰레드 세이프하다. (읽기 전용 값은 예외)

 

댓글