ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디자인 패턴에 대한 고찰(1) - 싱글턴
    Unity/Unity 스파르타 2024. 2. 17. 16:59
    728x90

    디자인패턴, 싱글턴에 대해 알아보고 이에 대해 고찰해 보자..

     

    싱글턴패턴은 인스턴스가 오직 하나만 생성됨으로 인스턴스의 유일성을 보장해 항상 동일한 인스턴스를 사용할 수 있습니다. 

    또한 전역적 접근으로 어디서든 동일한 인스턴스에 접근해 코드의 유연성과 확장성을 향상 시킬 수 있습니다 .

    하지만 항상 주의 해야할 점은 싱글턴패턴의 클래스의 인스턴스는 무조건 1개만 존재해야하며 전역적으로 관리하기 때문에 싱글턴 패턴의 클래스가 많아질 수록 메모리 누수 문제와 성능상 좋지않은 영향을 줄 가능성이 높습니다.

     

    일반적인 싱글턴 

    public class SingletonExample : MonoBehaviour
    {
        private static SingletonExample _instance;
    
        public static SingletonExample Instance
        {
            get
            {
                // 인스턴스가 없을 경우 새로 생성합니다.
                if (_instance == null)
                {
                    // Scene에서 이미 있는지 확인하고 없으면 생성합니다.
                    _instance = FindObjectOfType<SingletonExample>();
    
                    // Scene에 존재하지 않는 경우 새로운 GameObject를 생성하여 싱글턴 인스턴스를 추가합니다.
                    if (_instance == null)
                    {
                        GameObject singletonObject = new GameObject();
                        _instance = singletonObject.AddComponent<SingletonExample>();
                        singletonObject.name = "SingletonExample";
                        DontDestroyOnLoad(singletonObject);
                    }
                }
                return _instance;
            }
        }
    
        private void Awake()
        {
            // 이미 싱글턴 인스턴스가 존재하면 새로 생성된 인스턴스를 파괴합니다.
            if (_instance != null && _instance != this)
            {
                Destroy(this.gameObject);
            }
        }

    싱글턴 활용 심화 

    아래 코드는 인스펙터에 싱글턴 매니저 오브젝트들을 하나하나 다 만들지 않고 하나의 매니저에서 한번에 관리하기 위한 코드 입니다.

    좋은점은 인스펙터창이 깔끔해지고 다른 매니저급 클래스들을 관리하고 사용하기 좋습니다.

    특히, Scene 마다 사용 되어져야하는 UI 의 경우에 매우 용이합니다.

    허나, 아래 매니저 클래스에서는 매니저급 클래스를 New 생성자를 통해 만들어 지고있기 때문에 해당 매니저급 클래스에서는 MonoBehaviour 를 상속 받을 수 없습니다. 그렇게 때문에 주로 프리팹화 해놓은 리소스폴더 내의 프리팹 파일을 불러와 사용하게 됩니다.

    그래서 아래 매니저 클래스에서 사용될, 특히 UI매니저의 경우에는 구조적으로 설계할 필요성이 있습니다.

    매우 번거로운 과정일 수 있지만 인스펙터창을 매우 깨끗하게, 효율적으로 관리할 수 있다는 장점이 있습니다.

    ex)UI_Base(해당 UI의 특정 컴포넌트들을 딕셔너리로 담아 사용가능한 클래스) -> UI_Popup(UI에 그래픽요소들을 관리) ->UIManager(캔버스 생성및 UI생성)

    public class Manager : MonoBehaviour
    {
        static Manager _instance;
        static Manager Instance { get { Init(); return _instance; } }
    
        GameManager _gameManager = new GameManager();
        UIManaer _uiManager = new UIManaer();
        
        public static GameManager GameManager => Instance?._gameManager;
        public static UIManaer UI => Instance?._uiManager;
        
        private void Awake()
        {
            Init();
        }
    
    
        private static void Init()
        {
            if (_instance == null)
            {
                GameObject go = GameObject.Find("@Managers");
    
                if (go == null)
                {
                    go = new GameObject("@Managers");
                    go.AddComponent<Manager>();
                }
                DontDestroyOnLoad(go);
                _instance = go.GetComponent<Manager>();
            }
        }
    }
    728x90
Designed by Tistory.