단 하나의 인스턴스를 생성하면 되는 경우 → '싱글턴' 사용

싱글턴이란 ?

하나의 해당 클레스에서 단 하나의 인스턴스만 만들도록 보장하는 방법이다. 즉, 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다.

싱글턴을 사용해야 하는 경우

객체를 여러번 생성할 필요가 없고 단 한 번만 생성하면 되는 경우에 싱글톤을 사용하면 된다.

싱글턴의 장점

싱글톤 패턴은 하나의 인스턴스만을 재사용하게 된다. 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴이다. 이로 인해 인스턴스가 필요 할 때 똑같은 인스턴스를 만들어 내는 것이 아니라, 동일(기존) 인스턴스를 사용하게한다. 따라서 객체를 여러 번 생성할 필요가 없는 경우에 싱글톤을 사용하면 불필요한 자원 낭비나 오버헤드 등을 막을 수 있다.

싱글턴의 단점

싱글톤 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유시킬 경우 다른 클래스의 인스턴스들 간에 결합도가 높아져 “개방-폐쇄 원칙” 을 위배하게 된다. (=객체 지향 설계 원칙에 어긋남)

따라서 수정이 어려워지고 테스트하기 어려워진다.

또한 멀티쓰레드환경에서 동기화처리를 안하면 인스턴스가 두개가 생성된다든지 하는 경우가 발생할 수 있음

개발을 할때 항상 들어온 goto는 쓰면 안돼! 전역 객체는 안 좋은거야! 라는 말 처럼 꼭 필요한 경우아니면 지양해야함. // 적절히 잘 쓰면 아주 좋음, (그게 어렵지)

싱글턴을 만드는 방식

기본 원칙

  • 생성자는 private으로 감춰야 한다.
  • 유일한 인스턴스

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

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

    private Elvis() { ... }
    ...
}
  • 생성자는 private으로 감춰야 한다. (private Elvis() { ... })
  • public static final를 활용해 유일한 인스턴스에 접근할 수 있는 수단을 만들어야 한다. (public이나 protected 생성자가 없으므로 Elvis 클래스가 초기화될 때 만들어진 인스턴스가 전체 시스템에서 하나뿐임이 보장된다. 즉, 클라이언트는 다른 방법으로 인스턴스를 만들 수 있는 방법이 없다.)

    static으로 INSTANCE를 선언했기 때문에, INSTANCE를 호출 할 때마다 새로운 인스턴스가 불러지는 것이 아니라 동일한 인스턴스가 불러진다.

장점

  • 해당 클래스가 싱글턴임이 API에 명백히 드러난다.
  • public static 필드가 final이니 절대로 다른 객체를 참조할 수 없다.
  • 코드가 간결하다.

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

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

    private Elvis() { ... }

    public static Elvis getInstance() {
            return INSTANCE;
    }
    ...
}
  • 생성자는 private으로 감춰야 한다. (private Elvis() { ... })
  • 정적 팩터리 메서드를 활용해 유일한 인스턴스에 접근할 수 있는 수단을 만드는 방법이기 때문에, private static final Elvis INSTANCE = new Elvis();에서 방법 1과는 달리 접근 제어자를 public이 아닌 private을 쓴 것이다.
  • public static Elvis getInstance() { ... }를 활용해 유일한 인스턴스에 접근할 수 있는 수단을 만들어야 한다. (public이나 protected 생성자가 없으므로 Elvis 클래스가 초기화될 때 만들어진 인스턴스가 전체 시스템에서 하나뿐임이 보장된다. 즉, 클라이언트는 다른 방법으로 인스턴스를 만들 수 있는 방법이 없다.)

    static으로 INSTANCE를 선언했기 때문에, INSTANCE를 호출 할 때마다 새로운 인스턴스가 불러지는 것이 아니라 동일한 인스턴스가 불러진다.

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

public enum Elvis {
    INSTANCE;
    ...
}

References