guricode

Singleton Pattern(싱글톤 패턴) 본문

앱/Flutter&Dart

Singleton Pattern(싱글톤 패턴)

agentrakugaki 2025. 7. 22. 19:43

싱글톤 패턴이란?

싱글톤(Singleton)은 클래스의 인스턴스를 오직 하나만 생성하도록 보장하는 디자인 패턴이다.
주로 전역적으로 상태를 공유해야 하는 경우 사용한다.

예를 들면 앱의 설정 정보, 데이터베이스 연결, 로그 기록 등의 기능에 활용된다.


왜 싱글톤을 사용할까?

  • 인스턴스를 한 번만 생성하고 재사용해야 할 때
  • 여러 객체에서 동일한 인스턴스를 참조해야 할 때
  • 메모리 낭비를 막고, 상태를 전역으로 관리하고 싶을 때

싱글톤 기본 구조 (Dart 예시)

class Singleton {
  static final Singleton _instance = Singleton._internal();

  // 외부에서 인스턴스를 생성하지 못하게 private 생성자
  Singleton._internal();

  // 생성된 인스턴스를 반환
  factory Singleton() {
    return _instance;
  }

  String data = '싱글톤 데이터';
}

사용 방법:

void main() {
  var s1 = Singleton();
  var s2 = Singleton();

  print(s1 == s2); // true
}

더보기

키워드 설명

1. static

  • 클래스의 인스턴스와 상관없이 클래스 자체에 속하는 변수나 메서드를 정의할 때 사용.
  • 인스턴스를 생성하지 않아도 접근할 수 있다.
  • 싱글톤에서 유일한 인스턴스를 static으로 선언하여 프로그램 어디에서든 동일한 인스턴스를 참조하게 만든다.

예시:

static final Singleton _instance = Singleton._internal();

2. final

  • 변수에 한 번 값이 할당되면 변경할 수 없다.
  • 싱글톤에서는 인스턴스를 단 한 번만 생성하고 절대 다른 인스턴스로 대체되지 않도록 final로 선언한다.

예시:

static final Singleton _instance = Singleton._internal();

3. factory

  • 생성자를 대신하여 인스턴스를 반환하는 함수.
  • 일반 생성자와 달리, 새로운 인스턴스를 반환할 수도 있고, 기존 인스턴스를 반환할 수도 있다.
  • 싱글톤에서는 새 인스턴스를 생성하지 않고 이미 생성된 인스턴스를 반환하는 역할을 한다.

예시:

factory Singleton() {
  return _instance;
}

정리

키워드 설명 싱글톤에서의 역할
static 클래스에 귀속 인스턴스를 클래스에 귀속시켜 전역에서 사용
final 값 변경 불가 한번 생성된 인스턴스를 변경하지 않음
factory 생성자 대신 인스턴스를 반환 새로 생성하지 않고 기존 인스턴스를 반환

 

 

싱글톤의 장점

  • 전역 인스턴스를 통해 데이터 일관성 유지
  • 메모리 절약 (인스턴스 재사용)
  • 상태 공유가 용이

싱글톤의 단점

  • 전역 상태가 많아지면 코드가 복잡해지고 테스트 어려움
  • 의존성 주입이 어렵다
  • 멀티스레드 환경에서는 동기화가 필요할 수 있다

실무에서 싱글톤을 사용할 때 주의할 점

  • 꼭 필요한 경우에만 사용한다
  • 전역 상태로 인해 의존성이 꼬이지 않도록 설계한다
  • 테스트 환경에서 Mock 처리 등을 쉽게 하기 위해 인터페이스와 함께 설계하는 것이 좋다

 

아래 싱글톤 예제코드를 보며 생각해보자

class Singleton {
  // 1. static과 final로 유일한 인스턴스 생성
  static final Singleton _instance = Singleton._internal();

  // 2. factory 생성자: 항상 동일한 인스턴스를 반환
  factory Singleton() {
    return _instance;
  }

  // 3. private 생성자: 외부에서 직접 생성 방지
  Singleton._internal();

  // 4. 클래스의 메서드 예시
  void sayHello() {
    print('Hello, I am a Singleton instance');
  }
}

void main() {
  var s1 = Singleton();
  var s2 = Singleton();

  s1.sayHello();

  print(identical(s1, s2)); // true, 두 인스턴스가 동일한 객체인지 확인
}