본문 바로가기

STUDY/이펙티브자바

2-3) private 생성자나 열거 타입(enum)으로 싱글톤을 보장하라

싱글톤 패턴

 

MyClass myClass1 = ...
MyClass myClass2 = ...

// true
System.out.println(myClass1 == myClass2);

싱글톤 패턴은 클래스가 오로지 하나의 인스턴스를 만들 수 있도록 하는 패턴이다. 무상태 객체나 필요에 의해 시스템에 하나의 객체만 존재해야하는 경우 싱글톤 패턴을 사용한다. 싱글톤 패턴을 구현하는 방식은 크게 3가지가 존재한다.

 

 


public static final 필드 방식의 싱글톤

 

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

    private Elvis() { }

    public void leaveTheBuilding() {
        System.out.println("Whoa baby, I'm outta here!");
    }
}

 

Elvis 클래스는 생성자가 private로 되어있기 때문에 외부에서 객체를 생성할 수 없다. INSTANCE 객체가 Elvis 클래스의 유일한 객체가 된다. public static final 필드 방식의 장점은 해당 클래스가 싱글톤 클래스라는게 명백히 드러난다는 것이다. 그리고 클래스의 코드 또한 매우 간결해진다. 다만 추후 해당 클래스를 싱글톤이 아니게 바꾸거나, 상황에 따라 다른 인스턴스를 만들거나 하는 유연성이 떨어진다.

 

 


정적 팩토리 방식의 싱글톤

 

public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { }
    public static Elvis getInstance() { return INSTANCE; }

    public void leaveTheBuilding() {
        System.out.println("Whoa baby, I'm outta here!");
    }
}

 

Elvis 클래스는 생성자가 private로 되어있기 때문에 외부에서 객체를 생성할 수 없다. 따라서 getInstance 메소드를 통해서 하나의 객체만을 사용하게 된다. 정적 팩토리 메소드 방식의 장점은 추후 싱글톤이 아니게 바꾸거나 상황에 따라 다른 객체를 반환하도록 코드를 수정하여도 getInstance 메소드를 사용하는 코드에는 영향이 없다는 것이다. 즉 유연한 코드 수정이 가능하다. 다만 getInstance가 매번 같은 객체를 반환하는지 다른 객체를 반환하는지는 개발자가 확인해 보아야 한다. 

 

 


열거 타입(enum) 방식의 싱글톤

 

public enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() {
        System.out.println("Whoa baby, I'm outta here!");
    }
}

 

Enum은 기본적으로 생성자가 private이기 때문에 외부에서 객체를 생성할 수 없다. 개발자는 public static final 필드 방식 처럼 객체를 사용한다. 하지만 enum의 기본 특성 때문에 코드가 매우 간결해진다. 따라서 enum 방식의 싱글톤이 일반적으로 추천되지만 다른 클래스를 상속해야 해야하는 경우 등 사용할 수 없는 상황이 존재한다.

 

 


참고

 

 - [자바] 싱글톤 정말 한개만 만들어봅시다.

728x90