디자인 패턴

싱글톤 패턴

달리는 꿈나무 2023. 9. 4. 12:11

생성 패턴의 일종으로 인스턴스를 오직 한 개만 제공하는 클래스

시스템 런타임, 환경 세팅에 대한 정보 등, 인스턴스가 여러 개일 때 문제가 생길 수 있는 경우가 존재

-> 인스턴스를 오직 한 개만 만들어 제공하는 클래스가 필요

 

싱글톤 패턴 구현 방법

1. private 생성자에 static 매서드

public class Settings {

   private static Settings instance; 
    
   private Settings() { }

   public static Settings getInstance() { 
    	if (instance == null) {
	  instance = new Settings(); 
        }
        
	 return instance; }
}
  • 이 방법은 인스턴스가 null인지 아닌지 체크하는 방식으로 가장 기초적인 방식이다. 
  • 다만 이 방법은 멀티스레드 환경에 부적합하다. 
  • 스레드가 거의 동시에 들어왔을 때 만약 if문 안에서 아직 Settings()가 실행되지 않았으면 잘못하여 새로 생성이 되버린다. 

2. 동기화(Synchronized)를 사용해 멀티 스레드 환경에서 안전하게 만드는 방법

public static synchronized Settings getInstance() { 
  if (instance == null) {
    instance = new Settings(); 
  }
  return instance; 
}
  • 멀티 스레드 환경에서 적합하게 구현하기 -> Synchronized 키워드
  • 다만 이 키워드를 사용하면 동기화 처리 때문에 성능 저하가 일어난다.

3. 이른 초기화(Eager Initialization)을 사용하는 방법

private static final Settings INSTANCE = new Settings(); 

private Settings() {}

public static Settings getInstance() { 
	return INSTANCE;
}
  • final은 불변 선언이다. 참고로 final로 선언하면 대문자로 작성해주면 좋다.
  • 이른 초기화는 생성 시점이 클래스를 만들 때 동시에 만들어지므로 고정되어있다는 단점이 존재한다.

4. Double Checked Locking으로 효율적인 동기화 블럭 만들기

public static Settings getInstance() {
  if (instance == null) {
    synchronized (Settings.class) { 
      if (instance == null) {
        instance = new Settings(); 
          }
      } 
    }
  return instance; 
}
  • 클래스 싱크로나이즈
  • 매번 동기화 매커니즘을 실행하지 않는다.
  • 멀티 스레드가 빈번할 경우 if문에 여러 스레드가 들어오는데 그 때 거를 수 있다.
  • 또한 적재적소의 상황에서 사용 가능하다.

4. Static Inner Class를 사용하는 방법

private Settings() {}

private static class SettingsHolder {
  private static final Settings SETTINGS = new Settings();
}

public static Settings getInstance() { 
  return SettingsHolder.SETTINGS;
}
  • 멀티 스래드 환경에서도 안전하다.
  • Lazy Loading도 가능하다.
  • 복잡하지 않다.
  • 추천

5. Enum을 사용하는 방법

public enum Settings { 
  INSTANCE;
}
  • 리플렉션 방지가 가능하다.
  • 직렬화 역직렬화에 굉장히 안전하다.
  • 다만 Enum 클래스 특성상 미리 메모리에 생성된다는 점이 단점이다.
  • 또한 상속이 불가능하다. 상속과 Lazy Loading이 필요하면 Static Inner Class가 제일 무난하다.
  • 추천

 

싱글톤 패턴 실무 사용 방식

  • 스프링에서 빈의 스코프 중에 하나로 싱글톤 스코프
  • 자바 java.lang.Runtime
  • 다른 디자인 패턴(빌더, 퍼사드, 추상 팩토리 등) 구현체의 일부로 쓰이기도 한다.

 

 

출처: 백기선의 코딩으로 학습하는 GoF의 디자인 패턴