개발자가 되고 싶은 개발자

[Design Pattern] Singleton Pattern 본문

Dev/CS

[Design Pattern] Singleton Pattern

Fullth 2023. 3. 13. 23:38

싱글턴 패턴은

특정 클래스에 객체 인스턴스가 하나만 만들어지도록 해주는 패턴.
클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다.

"스스로에게 어떻게 하면 한 클래스의 인스턴스를 두 개 이상 만들지 않게 하지?" 라는 질문을 던져보기.

고전적인 싱글턴 패턴 구현법

export class Singleton {    
  // 하나뿐인 인스턴스를 저장할 변수
  private static uniqueInstance: Singleton;

  // 생성자를 private으로 선언하여 외부에서 생성할 수 없도록 한다.
  private Singleton() { }

  public static getInstance(): Singleton { 
    if (!Singleton.uniqueInstance) {
      Singleton.uniqueInstance = new Singleton();
    }
    return Singleton.uniqueInstance;
  }
}

위와 같은 방법을 이용하면 public으로 지정된 생성자가 없기 때문에, 자유롭게 새 인스턴스를 만들 수 없다.

객체가 필요할 때는 인스턴스를 달라고 요청하는 방법으로만 이용한다.

그래서 static으로 작성된 getInstance() 메서드가 존재한다.
(이미 만들어져 있는 경우, 다른 객체에서 호출되면 해당 객체에 호출된다.)

아래는 위의 싱글턴 예시가 문제 있다는 것을 알려주기 위한 예시 코드.

export class ChocolateBoiler {
  private empty: boolean;
  private boiled: boolean;

  private static uniqueInstance: ChocolateBoiler;

  private ChocolateBoiler() {
    this.empty = true;
    this.boiled = false;
  }

  public static getInstance(): ChocolateBoiler {
    if (!ChocolateBoiler.uniqueInstance) {
      ChocolateBoiler.uniqueInstance = new ChocolateBoiler();
    }
    return ChocolateBoiler.uniqueInstance;
  }

  public fill(): void {
    if (this.isEmpty()) {
      this.empty = false;
      this.boiled = false;
      this.boil();
    } 
  }

  public drain(): void {}

  public boil(): void {}

  public isEmpty(): boolean {
    return this.empty;
  }

  public isBoiled(): boolean {
    return this.boiled;
  }
}

문제점

멀티 스레드 환경에서 아직 초콜릿이 끓고 있는데도 불구하고, fill 메서드가 호출되어 새로운 재료를 넣고 말아 넘치는 현상 발생.

멀티 스레드 환경에서 동시에 호출되었을 때, if 조건문에서 uniqueInstanc 인스턴스가 있는지 동시에 체크한다면, 문제가 된다.

Java에서는 synchronized 키워드만 추가해주면 해결된다.

JavaScript는 싱글 스레드이긴 하지만, Event Loop등 덕분에 동시성이 존재하기 때문에, 동일한 문제가 일어날 수 있고 그래서 async 등으로 비동기 제어가 필요하다.
(테스트 해보기)

사실 생성할 때만 일어나는 문제이기 때문에, 필요할 때 생성하는 것이 아닌 처음부터 생성하는 방식으로 멀티스레딩 문제를 해결할 수 있다.

주의점

싱글턴 패턴을 사용하면 loose coupling principle을 위반하기 쉬워진다.관점에 따라 single principle responsibility를 위반을 지적할 수 있다.

enum

동기화, 클래스 로딩 리플렉션 등의 문제를 enum으로 싱글턴을 생성하는 것을 통해 해결할 수 있다.

책은 Java 언어로 작성되어 있고, 공부하면서 TypeScript로 변환하여 작성하였기 때문에 잘못된 부분이 있을 수 있습니다.

'Dev > CS' 카테고리의 다른 글

[DataStructure] Queue  (0) 2021.11.23
[Web] REST  (0) 2021.03.07
[WEB] REST 이해하기  (0) 2021.01.11