Singleton pattern

오현재·2024년 11월 25일

Singleton Pattern 이란

싱글턴 패턴(Singleton Pattern) 은 디자인 패턴 의 일종으로써, 객체의 인스턴스가 오로지 한개만 생성되도록 설계하는 것이다.

디자인 패턴이란 흔히 발생하는 문제에서 최적화된 해결책을 정리한 것

그렇다면 싱글턴 패턴 은 어떠한 문제를 해결할 수 있을까?

  1. 똑같은 데이터를 여러곳에서 사용할 필요가 있을 때 활용할 수 있다.

    예를들어, 우리는 여러곳에서 사용 되는 똑같은 데이터가 있다면, 이를 각 함수나 코드 안에서 지역 변수로 선언하지 않고, 전역 변수로써 사용할 수 있다. 그렇게 되면 메모리 를 절약할 수 있는 이점이 있다. 이러한 개념을 클래스에 대입한 것을 싱글턴 패턴이라고 볼 수 있다.

  2. 클래스 간의 데이터 공유가 필요할 때 활용할 수 있다.

    1.과 같은 이유로 싱글턴 패턴으로 생성된 클래스의 인스턴스는 전역적으로 접근이 가능하다. 그렇기에 다른 클래스의 인스턴스들도 접근하여 사용이 가능하게 된다.

    주의할 점은 멀티 스레드 환경에서, 싱글턴 클래스의 인스턴스의 데이터에 동시에 접근할 수 있다는 점이다.

  3. 객체가 가지는 기능이 무거울 때 활용할 수 있다.

    싱글턴 패턴 의 클래스를 만들면 인스턴스가 필요할 때마다 생성하는 것이 아닌, 인스턴스를 생성해놓고 필요할 때 사용하게 된다.

    대표적으로 데이터베이스 연결 모듈을 예로 들 수 있는데, 데이터베이스에 접속하는 작업(I/O 바운드)은 그 자체로 무거운 작업에 속하며 또한 한번만 객체를 생성하고 돌려쓰면 되지 굳이 여러번 생성할 필요가 없기 때문이다.

    이밖에도 로그 기록, 캐싱, 사용자 설정 등에 이용된다. 따라서 앱에서 유일하면 좋을 것을 싱글톤 객체로 만들면 된다고 보면 된다.

구현

Java

다음은 JAVA 에서 오직 private static 변수를 이용하여 구현하는 방법이다.

  1. 인스턴스를 private static 변수로 생성
  2. getInstance() 에서 기존 인스턴스가 없다면 인스턴스 생성
  3. 기존 인스턴스가 있다면 외부 생성자를 막는다.

핵심적인 부분은, 인스턴스 생성을 getInstance() 라는 해당 클래스 내 메서드에서 하고, 기존 인스턴스가 있다면 외부 생성자를 막는 부분이다.

문제점은 아까 말했듯, 멀티 스레드 환경에서 스레드세이프 하지 않다. 만약 A 와 B 에 동시에 접근하다면 문제가 된다.

public class Settings {
	private static Settings instance;
	private Settings() {
		/* ... */public static Settings getInstance () {
		if (instance == null) { // A
			instance = new Settings(); // B
		}
		return instance;
	}
}

이를 Java 에선 synchronized 키워드를 활용하여 해결할 수 있다.

public class Settings {
	private static Settings instance;
	private Settings() {
		/* ... */public synchronized static Settings getInstance () {
		if (instance == null) {
			instance = new Settings();
		}
		return instance;
	}
}

Javascript

Javascript 에서는 Java 와 매우 유사한 코드로 구현할 수 있다.

export class EnemyStore {
  private static instance: EnemyStore;
  public static getInstance() {
    if (!this.instance) {
      this.instance = new EnemyStore();
    }
    return this.instance;
  }

Single Thread

앞서 멀티스레드 환경에서 싱글턴 패턴을 사용할 때 생길수 있는 문제점인 싱글턴 패턴 클래스의 인스턴스에 동시에 접근할 수 있는 문제는 Javascript 에서는 자유로울 수 있다.
Javascript 는 싱글 스레드 언어로, 기본적으로 한 번에 하나의 작업만 처리할 수 있기 때문이다.

다만 예외적으로 Javascript 에서도 멀티 스레드와 같은 환경이 발생할 수 있는데, Web Worker 를 사용할 때이다.

웹 워커(Web worker)는 스크립트 연산을 웹 어플리케이션의 주 실행 스레드와 분리된 별도의 백그라운드 스레드에서 실행할 수 있는 기술입니다. 웹 워커를 통해 무거운 작업을 분리된 스레드에서 처리하면 주 스레드(보통 UI 스레드)가 멈추거나 느려지지 않고 동작할 수 있습니다.

이처럼 Web Worker 는 별도의 스레드에서 스크립트를 실행할 수 있는 기능이기 때문에, Web Worker 에서 싱글턴 패턴 클래스의 인스턴스에 접근하는 스크립트가 실행되고, 주 스레드에서 또한 싱글턴 패턴 클래스의 인스턴스에 접근하려고 시도한다면 동시성 문제가 발생할 수 있을 것 이다.

따라서 앱에서 싱글턴 패턴의 클래스와 Web Worker 를 동시에 사용한다면, 주의해서 사용할 필요가 있을 것 이다.
Reference

[10분 테코톡] 아서의 싱글턴 패턴과 정적 클래스

💠 싱글톤(Singleton) 패턴 - 꼼꼼하게 알아보자

profile
안녕하세요. 환영합니다. 프론트엔드 개발자 오현재입니다.

0개의 댓글