[Unity] C# - 싱글톤(SingleTon) 코드

suhan0304·2024년 7월 1일

Design Pattern

목록 보기
1/16
post-thumbnail

싱글톤(SingleTon Pattern)?

싱글톤 패턴은 객체 지향 프로그래밍에서 특정 클래스가 단 하나의 인스턴스를 생성하여 사용하기 위한 패턴이다. 생성자를 여러 번 호출하더라도 인스턴스가 하나만 존재하도록 보장하여 애플리케이션에서 동일한 객체 인스턴스에 접근할 수 있도록 한다.


장점

커넥션 풀, 스레드 풀, 디바이스 설정 객체 등과 같은 경우 인스턴스를 여러 개 만들게 되면 불필요한 자원을 사용하게 되고, 프로그램이 예상치 못한 결과를 낳을 수 있다. 따라서 객체를 필요할 때 마다 생성하는 것이 아닌 단 한 번만 생성하여 전역에서 이를 공유하고 사용할 수 있게 하기 위해 싱글톤 패턴을 사용한다.


단점

객체 지향 설게 원칙 중 개방-폐쇄 원칙이란 것이 존재한다. 싱글톤 인스턴스가 혼자 너무 많은 일을 하거나, 많은 데이터를 공유시키면 다른 클래스들 간의 결합도가 높아지게 되는데, 이 때 개방-폐쇄 원칙이 위배된다. 결합도가 높아지게 되면, 유지보수가 힘들고 테스트도 원할하게 진행할 수 없는 문제점이 발생한다.

또한, 멀티 스레드 환경에서 동기화 처리를 하지 않았을 때, 인스턴스가 2개가 생성되는 문제도 발생할 수 있다. 따라서, 반드시 싱글톤이 필요한 상황이 아니면 지양하는 것이 좋다고 한다.(설계 자체에서 싱글톤을 원할하게 할 자신이 있으면 괜찮다.)


싱글톤 패턴은 게임 내에서 전역적으로 액세스할 수 있어야 하는 단일 리소스나 시스템(예: 게임 매니저, 오디오 매니저 또는 게임 설정 매니저)을 관리해야 할 때 주로 사양한다.


SingleTon (1)

public class Singleton
{
    private static Singleton instance;
 
    private Singleton() { }
 
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

Singleton Instance = Singleton.Instance;

SingleTon (2)

using UnityEngine;
 
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;
 
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = (T)FindObjectOfType(typeof(T));
                
                if (instance == null)
                {
                    var ob = new GameObject(typeof(T).Name);
                    instance = ob.AddComponent<T>();
                }
            }
            
            return instance;
        }
    }
 
    protected void Awake()
    {
        if (instance == null)
        {
            instance = this as T;
            DontDestroyOnLoad(this.gameObject);
        }
        else if (instance != this)
        {
            Destroy(this.gameObject);
        }
    }
}

SingleTon(3)

public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    public static T Instance { get; private set; }
 
    private static System.Action<T> s_onAwake;
 
    public static void WhenInstantiated(System.Action<T> action)
    {
        if (Instance != null)
            action(Instance);
        else
            s_onAwake += action;
    }
 
    protected virtual void Awake()
    {
        if (!enabled)
            return;
 
        if (Instance != null)
        {
            Debug.LogWarning($"Another instance of Singleton {typeof(T).Name} is being instantiated, destroying...", this);
            Destroy(gameObject);
            return;
        }
    
        Instance = (T)this;
 
        InternalAwake();
 
        s_onAwake?.Invoke(Instance);
        s_onAwake = null;
    }
 
    protected void OnEnable()
    {
        if (Instance != this)
            Awake();
    }
 
    protected virtual void InternalAwake() { }
}
profile
Be Honest, Be Harder, Be Stronger

0개의 댓글