# 싱글톤 (Singleton) 패턴

# 싱글톤이란 무엇인가요?

하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴입니다.
하나의 인스턴스를 만들어 여러 모듈들이 공유하며 사용합니다.

# 예시 코드

  • 예시 1 : if문 사용 (Lazy-init 방식)
public class Singleton {
    private static Singleton instance;

    private Singleton() { }
    
    public static synchronized Singleton getInsatance() {
        if(instance == null) {
            instance = new Singleton();
        }

        return instance;    //instance가 이미 있을 때는, 그 instance 반환
    }
}
  • 예시 2 : static으로 바로 생성
public class Singleton {
    private static final Singleton instance = new Singleton(); //생성자를 한번은 호출해야 하니까 직접 넣어줌

    private Singleton() { }  //외부에서 생성자를 호출하지 못하게 private으로 설정

    public static Singleton getInsatance() {
        return instance;
    }
}

# 싱글톤을 사용하는 곳

데이터베이스 연결 모듈에 많이 사용됩니다.
ex1) Node.js에서 MongoDB데이터 베이스를 연결할 때 쓰는 mongoose 모듈
ex2) Node.js에서 MySQL 데이터베이스를 연결할 때

# 싱글톤의 장점은 무엇인가요?

  • 하나의 인스턴스만을 만들기 때문에, 고정된 메모리 영역을 사용하여 메모리 낭비를 방지할 수 있습니다.
  • 싱글톤 인스턴스는 전역으로 접근 가능하기 때문에, 데이터 공유가 쉽습니다.

# 싱글톤의 단점은 무엇인가요?

  • 모듈들간의 의존성이 높아집니다. 따라서, TDD(Test Driven Development)를 할 때 문제가 됩니다.
  • 멀티스레드 환경에서 동시성 문제 해결을 위해 'syncronized'를 사용해야 합니다. 'syncronized'는 다른 스레드들을 모두 제어하기 때문에, 프로그램 성능저하를 일으킬 수 있습니다.

# 싱글톤의 단점을 해결하기 위한 방법으로는 무엇이 있나요?

  • 의존성을 주입합니다. 메인모듈 하위에 의존성 주입자를 추가하여 의존성 주입자가 모듈들을 관리하면, 하위 모듈에 대한 메인 모듈의 의존성이 떨어져 단위 테스트를 하기 편리해집니다.
  • 스프링 컨테이너를 사용합니다.

    TIP

    스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리합니다.
    대표적인 예가 스프링 빈입니다.

# 싱글톤 대신 정적클래스를 사용하면 되지 않나요?

정적클래스를 사용하면, 성능면에서 우수할 수 있으나 interface의 사용이 불가능해집니다.
이는, 테스트용 객체(Stub)를 사용할 수 없게 만들어 효율적인 단위테스트를 방해할 수 있습니다.

# Reflection을 사용하면 싱글톤이 의미 없어지지 않나요?

enum 타입을 통해 싱글톤을 만들면 문제가 해결됩니다.

public enum SingletonEnum {
  INSTANCE;
  int value;

  public int getValue() {
    return value;
  }
  
  public void setValue(int value) {
    this.value = value;
  }
}

public class Test {
    public static void main(String[] args) {
    SingletonEnum singleton = SingletonEnum.INSTANCE;
    
    System.out.println(singleton.getValue());
    singleton.setValue(1);
  }
}

# 참고자료

출처: 주홍철.면접을 위한 CS 전공지식 노트.서울:길벗,2022.
출처: 정인상, 채홍석.JAVA 객체지향 디자인 패턴.서울:한빛미디어,2019.
출처: https://scshim.tistory.com/361 [책읽는 개발자_테드]