본문 바로가기
Programming/OOP

[Design Pattern] Singleton Pattern, 싱글톤 패턴

by TinKerBellBass 2022. 5. 2.
728x90
반응형

말도 많고 탈도 많은 패턴계의 뜨거운 감자 싱글톤 패턴.

개인적으로 디자인 패턴이라기보다 코딩 기법이라고 생각한다.

애플리케이션 전체적으로 단 하나의 인스턴스를 사용하기 위해 사용되는 코딩 기법.

 

싱글톤이 늘 논의가 되는 곳은 자바 세상이기도 하고

각 언어마다 멀티스레드 환경을 제어하는 방법이 다르기는 하지만

자바, 코틀린, 고, 타입스크립트에서 어떻게 구현하는지 알아보자.

자바에서 일반적으로 알려진 싱글톤 코딩 기법이 왜 멀티스레드에서 깨지는지 등의 논의는 접어두고

각 언어마다 내 마음에 든 기법을 하나씩 소개하려고 한다.

 

Java Singleton Pattern

멀티 스레드를 락으로 동기화하는 synchronized,

캐시가 아닌 항상 메인 메모리에서 인스턴스를 가져오는 volatile 등이 필요 없고,

지연 로딩이 가능한 Bill Pugh 라는 분이 고안한 방법이 제일 깔끔하고 마음에 든다.

 

싱글톤 인스턴스를 생성하는 정적 메서드인 getInstance 가 실행되기 전까지

내부 클래스인 SingletonInner 는 로딩되지 않는다.

즉 지연 로딩되기 때문에 메모리 낭비가 없다.

그리고 클래스가 로드될 때 인스턴스가 생성되므로 스레드 세이프하다.

public class Singleton {
    
    private Singleton(){}
    
    private static class SingletonInner{
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonInner.INSTANCE;
    }
}

 

Kotlin Singleton Pattern

자바의 싱글톤 논란이 싫었는지 코틀린은 언어 차원에서 싱글톤을 지원한다. 

object 라는 객체를 단 한 번만 생성하게 해주는 키워드로 스레드 세이프한 싱글톤 생성 끝.

object 안에 생성된 필드나 메서드는 인스턴스 생성 없이

정적 필드, 정적 메서드처럼 object 이름을 사용해서 호출할 수 있다.

ojbect Singleton {
	val field: string = "singleton"
	fun method() {...}
}

fun main(args: Array<String>) { 
	Singleton.field
	Singleton.method()
}

 

Go Singleton Pattern

go 의 경우 sync 패키지의 sync.Once 를 이용해서 싱글톤을 구현하는 것이 제일 깔끔한 것 같다.

sync.Once 의 Do 메서드는 파라미터로 전달된 함수를 딱 한 번만 실행하며 스레드 세이프하다.

type singleton struct {}

 var instance *singleton
 var once sync.Once

 func GetInstance() *singleton {
     once.Do(func() {
         instance = &singleton{}
     })
     return instance
 }

 

Typescript Singleton Pattern

브라우저가 멀티 스레드이기 때문에 런타임 환경은 멀티 스레드이지만

자바스크립트는 콜 스택을 하나 가지는 싱글 스레드로 동작하기 때문에

자바에서 스레드 세이프하지 않은 일반적인 싱글톤 패턴으로 구현하면 된다.

class Singleton {
	private static INSTANCE: Singleton;

	private constructor() {}
  
	public static getInstance() {
		if (!Singleton.INSTANCE) {
			Singleton.INSTANCE = new Singleton();
		}
		return Singleton.INSTANCE;
	}
}

전체 소스는 https://github.com/Jongwon-Hyun/design_pattern

Spring  Container 와 Singleton

스프링 기동시에 스프링 빈은 생성되고 스프링 컨테이너에 보관된다.

스프링 빈은 @Scope 어노테이션으로 스코프를 따로 지정하지 않는 한 싱글톤이며,

@Lazy 등의 어노테이션을 사용하지 않는 한 생성할 빈들을 모든 생성한 후 의존성 주입까지 완료시킨다.

즉 기본 스코프가 싱글톤이며 즉시 로딩이다.

그리고 스프링 컨테이너는 생성된 빈들을 싱글톤처럼 관리한다.

 

 

728x90
반응형

댓글