Design Pattern - Singleton Pattern (싱글톤 패턴)

2025. 10. 20. 14:50·C#

싱글톤 패턴 (Singleton Pattern)

프로그램 전체에서 단 하나의 인스턴스만 존재하도록 보장하고, 어디에서든 그 인스턴스에 접근할 수 있게 하는 디자인 패턴이다.

프로젝트 내의 전역 관리자 같은 역할을 하는 구조다.

  • 인스턴스가 하나만 생성됨 (유일성 보장)
  • static 변수를 통해 어디서든 접근 가능 (전역 접근성)
  • 필요할 때 자동으로 생성되며, 이미 있으면 새로 만들지 않음
  • 주로 게임에서 상태 관리나 시스템 매니저 역할에 사용

Unity에서는 씬이 분리되어 있고 여러 스크립트가 서로 다른 오브젝트 위에서 동작한다.

이때 "게임 전체 상태"를 한 곳에서 관리해야하는 경우가 있다.

  • 씬이 바뀌어도 유지돼야 하는 정보 (플레이어 점수, 설정값, 능력치 등)
  • 전역적으로 접근해야 하는 시스템 (사운드, 데이터, UI 등)
  • 게임 전체를 제어하는 중앙 관리자 (GameManager. SceneManager 등)

이런 객체를 매번 new로 만들면 매번 새로운 인스턴스가 생기고 상태가 초기화 된다.

하지만 싱글톤은 프로그램 전체에서 단 하나만 유지하기 때문에 중복 생성이나 데이터 손실을 방지할 수 있다.

 

 

장점

전역 접근성 어디서든 쉽게 접근 가능 (GameManager.Instance)
유일성 보장 단 하나의 인스턴스만 유지
데이터 공유 용이 여러 씬 간 정보 유지에 유용 (DontDestroyOnLoad)
결합도 감소 단일 인스턴스의 전역적 접근을 보장하기 때문에 오브젝트들이 서로 참조하고 있는 결합도를 낮출 수 있다

 

단점

결합도 증가 여러 클래스가 싱글톤에 직접 의존하면 구조가 얽힘
테스트 어려움 인스턴스가 고정되어 단위 테스트 불리
메모리 관리 이슈 static을 사용해 정적 메모리 할당되므로, 싱글톤 객체가 많을수록 가용 메모리가 적어짐
또한 Destroy를 잊으면 씬 전환 후에도 계속 남음

 

즉, 편리하지만 남용하면 오히려 문제를 유발할 수 있으니 주의해야한다.

 

 

구현 예시

using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }
    
    void Awake()
    {
        // 이미 존재하는 인스턴스가 있다면 중복 제거
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        // 인스턴스 등록
        Instance = this;
        DontDestroyOnLoad(gameObject); // 씬 전환 시에도 유지
    }

    public int score = 0;

    public void AddScore(int amount)
    {
        score += amount;
        Debug.Log("현재 점수: " + score);
    }
}

 

이렇게 싱글톤으로 score를 관리하는 게임매니져를 구현한 상황을 가정해보자.

public class TestScript : MonoBehaviour
{
    void Start()
    {
        Debug.Log("TestScript AddScore");
        GameManager.Instance.AddScore(10);
    }
}
public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        Debug.Log("ExampleScript AddScore");
        GameManager.Instance.AddScore(10);
    }
}

 

그리고 각각 다른 곳에서 AddScore 메서드를 통해 점수를 추가하는 상황일 때,

모두 같은 GameManager.Instance를 참조하기 때문에 점수가 전역적으로 공유되어 같은 score를 가리키게 되어 증가시킨다.

 

 


 

제네릭 (Generic)

C#을 학습하면서 제네릭에 대한 것을 익혔었다.

제네릭이란 자료형을 일반화하여 재사용성과 안정성을 높이는 문법이다.

자료형을 나중에 지정하는 클래스 또는 메서드라고 볼 수 있다.

 

프로젝트가 커지면 GameManager, SoundManager, UIManager 등 유사한 구조의 싱글톤이 여러개 생길 수 있다.

모두 Awake() 에서 중복 제거하고, DontDestroyOnLoad()를 호출하는 코드를 반복하게 될 것이다.

 

제네릭을 이용하면 이러한 반복되는 패턴을 제거하고 통일할 수 있다.

public class Box<T>
{
    public T Value;
}

Box<int> intBox = new Box<int>();
Box<string> strBox = new Box<string>();

 

이렇게 작성하면 T 자리에 타입만 바꿔 넣어주면 하나의 코드로 여러 타입을 처리할 수 있게 된다.

 

장점

  • 형 안정성 : 잘못된 자료형 대입을 컴파일 단계에서 차ㅏ단
  • 성능 향상 : object 캐스팅 오버헤드 없음
  • 재사용성 : 자료형만 바꾸면 여러 타입에서 사용 가능
  • 유지보수성 : 코드 중복 없이 동일 로직 적용 가능

 

 

구현 예시

using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindAnyObjectByType<T>();

                // 그래도 없으면 새로 생성
                if (instance == null)
                {
                    GameObject obj = new GameObject(typeof(T).Name);
                    instance = obj.AddComponent<T>();
                }
            }
            return instance;
        }
    }

    protected virtual void Awake()
    {
        if (instance == null)
        {
            instance = this as T;
            DontDestroyOnLoad(gameObject);
        }
        else if (instance != this)
        {
            Destroy(gameObject);
        }
    }
}

 

public class GameManager : Singleton<GameManager>
{
    public int score;

    public void AddScore(int value)
    {
        score += value;
        Debug.Log($"현재 점수: {score}");
    }

    protected override void Awake()
    {
        base.Awake();
        Debug.Log("GameManager 초기화 완료");
    }
}

 

이렇게 다른 매니저도 상속만 하면 동일한 싱글톤 구조를 그대로 활용할 수 있다.

 

 

제네릭 싱글톤의 한계와 주의점

유일성 불변성 약화 T 타입마다 인스턴스가 별개로 존재하므로 프로그램 전체에서 유일성이 보장되지 않는다. 유일성을 추구하는 싱글톤과 확장성을 추구하는 제네릭의 개념이 서로 상충하게 되어 주의해야한다.
남용 시 결합도 상승 여러 클래스가 전역 싱글톤에 의존하면 구조가 엉킬 수 있다.
테스트 어려움 전역 인스턴스 단위 테스트시 독립성이 저하되고 특정 상황을 재현하는 것에 어려움이 생길 수 있다.
Destroy 누락 시 메모리 잔류 DontDestroyOnLoad로 인해 씬 교체 후에도 남아있을 수 있으니 파괴 타이밍에 주의해야한다.

 

 

 

활용 예시 - SceneManager

씬 전환이나 로딩 로직, 게임매니저 관리가 싱글톤의 대표적인 예다.

씬 관리를 하는 씬매니져를 예시 코드로 살펴보자

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneController : Singleton<SceneController>
{
    public void LoadScene(string sceneName)
    {
        SceneManager.LoadScene(sceneName);
    }

    public void ReloadScene()
    {
        Scene current = SceneManager.GetActiveScene();
        SceneManager.LoadScene(current.name);
    }
}

 

 

SceneController.Instance.LoadScene("Stage2");
SceneController.Instance.LoadScene(1);

 

string 으로 직접 씬 이름을 작성해서 호출할 수도, int 값을 통해 인덱스를 호출할 수도 있다.

씬 매니저가 전역적으로 존재하기 때문에 DontDestroyOnLoad를 통해 씬이 바뀌어도 씬매니져의 기능은 사라지지않고 남으며 원하는 곳에서 사용할 수 있다.

 

 

'C#' 카테고리의 다른 글

C# - 델리게이트(Delegae). 람다식과 캡쳐, 클로져 문제 (feat. useState)  (0) 2025.11.04
VisualStudioCode(VSC) 에서 한글 깨짐 이슈  (0) 2025.10.28
Design Pattern - Adapter Pattern (어댑터 패턴)  (0) 2025.10.17
C# - 콘솔로 "2중 버퍼링 (Double Buffering)" 구현하기  (0) 2025.10.15
C# - GetAsnycKeyState() 기반 실시간 키 입력 처리  (0) 2025.10.14
'C#' 카테고리의 다른 글
  • C# - 델리게이트(Delegae). 람다식과 캡쳐, 클로져 문제 (feat. useState)
  • VisualStudioCode(VSC) 에서 한글 깨짐 이슈
  • Design Pattern - Adapter Pattern (어댑터 패턴)
  • C# - 콘솔로 "2중 버퍼링 (Double Buffering)" 구현하기
ellug
ellug
Web / App / Game Dev
  • ellug
    dev.ellug
    ellug
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • Javascript (React, Next) (1)
      • C# (66)
      • Graphics (1)
      • Unity (25)
      • 프로그래머스 (0)
        • Lv.0 (0)
        • Lv.1 (0)
        • Lv.2 (0)
        • Lv.3 (0)
      • AI Agent (0)
      • StableDiffusion (0)
      • ETC (1)
      • 잡담 (0)
      • 유머 (0)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    최적화
    unity
    firebase
    콘솔
    Abstract
    네트워크
    터미널
    C#
    class
    스택
    delegate
    stack
    Design Pattern
    inputsystem
    Queue
    Network
    유니티
    useState
    큐
    알고리즘
    function
    자료구조
    interface
    list
    struct
    추상 클래스
    console
    게임
    Photon
    클래스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
ellug
Design Pattern - Singleton Pattern (싱글톤 패턴)
상단으로

티스토리툴바