디자인 패턴 - Singleton Pattern

rizz·2023년 5월 3일
0

디자인 패턴

목록 보기
2/4

📒 갈무리 - Singleton Pattern

📌 Singleton Pattern이란?

  • 메모리상으로 단 하나만 존재하며 언제 어디서든 사용할 수 있는 오브젝트를 만들 때 사용되는 패턴
  • 보통 게임 개발에서는 매니저, 관리자, 핸들러, 헬퍼 등에 사용된다.

📌 Singleton Pattern 예제

일반적인 경우

// C#

public class ScoreManager : MonoBehaviour
{
    public int score = 0;

    public int GetScore()
    {
        return score;
    }

    public void AddScore(int newScore)
    {
        score = score + newScore;
    }
}

public class ScoreAdder : MonoBehaviour
{
	// ScoreManager를 사용하는 곳마다 선언해야 함.
    public ScoreManager scoreManager;

    void Update()
    {
        // 마우스 좌클릭하는 순간.
        if (Input.GetMouseButtonDown(0))
        {
            // 사용할 객체를 링크하거나 Find해서 사용해야 함.
            // score에 5점을 더한다.
            scoreManager.AddScore(5);
            // score 출력.
            Debug.Log(scoreManager.GetScore());
        }
    }
}

 

싱글톤 패턴 적용

// C#

// 요즘 추세는 싱글톤 클래스 안에
// 필요한 여러 객체들을 들고 있게 만든다.
// 당연한 이야기지만 프로젝트나 개발자 성향에 따라 다를 수 있음.
public class ScoreManager : MonoBehaviour
{
    // 싱글톤.
    // 자기 자신을 참조할 static 변수.
    public static ScoreManager instance;

    private int score = 0;

	// 가장 먼저 호출되는 함수.
    private void Awake()
    {
        // 자기 자신을 static 변수로 초기화.
        instance = this;
    }

    public int GetScore()
    {
        return score;
    }

    public void AddScore(int newScore)
    {
        score = score + newScore;
    }
}

public class ScoreAdder : MonoBehaviour
{
    // 이 과정은 이제 필요하지 않음.
    // public ScoreManager scoreManager;

    void Update()
    {
        // 마우스 좌클릭하는 순간.
        if (Input.GetMouseButtonDown(0))
        {
            // 이제 사용할 때 링크를 걸거나 찾을 필요가 없다.
            // score에 5점을 더한다.
            ScoreManager.instance.AddScore(5);
            // score 출력.
            Debug.Log(ScoreManager.instance.GetScore());
        }
    }
}

 

객체 null 체크

// C#

	private static ScoreManager instance;
    
    // 없으면 에러를 발생시킴.
    public static ScoreManager GetInstance()
    {
        // ScoreManager 오브젝트를 만들어 놓고 이 스크립트를
        // 안 붙였거나 or ScoreManager 오브젝트가 아예 없는 상태일 때.
        if(instance == null)
        {
            instance = FindObjectOfType<ScoreManager>();
        }
        return instance;
    }

	// instance가 있다는 것을 보장하지만 뜻하지 않은 시점에 만들어질 수 있음.
	private static ScoreManager instance;
    
    public static ScoreManager GetInstance()
    {
        if (instance == null)
        {
            instance = FindObjectOfType<ScoreManager>();

            // 못 찾았다면 만듦
            if (instance == null)
            {
                // 빈 게임 오브젝트 생성할 때만 가능.
                // 일반적으로는 Instantiate 사용.
                GameObject container = new GameObject("Score Manager");
                // ScoreManager 컴포넌트(스크립트)를 붙여줌
                instance = container.AddComponent<ScoreManager>();
            }
        }
        return instance;
    }

 

싱글톤 클래스를 만들어 놓고, 그 클래스를 이용하여 원하는 Component를 싱글톤 객체로 생성

// C#

// 제네릭 타입은 Component로 한정
public class SingletonMonobehaviour<T> : MonoBehaviour where T : Component
{
    private static T m_instance;
    public static T Instance => m_instance; // Auto Property

    // m_instance가 있는 것을 보장.
    public static T GetOrCreateInstance()
    {
        if(m_instance == null)
        {
            m_instance = (T)FindObjectOfType(typeof(T));

            if (m_instance == null)
            {
                GameObject _newGameObject = new GameObject(typeof(T).Name, typeof(T));
                m_instance = _newGameObject.GetComponent<T>();
            }
        }
        return m_instance;
    }

    protected virtual void Awake()
    {
        // 자기 자신으로 초기화.
        m_instance = this as T;

        if (Application.isPlaying == true)
        {
            // scene과 scene이 전환될 때 특정 오브젝트가 계속 살아있어야 할 때 사용.
            // scene이 전활될 때 scene안에 존재하는 모든 오브젝트는 사라지게 되는데,
            // singleton은 scene이 전환되어도 살아있어야 하므로 DontDestroyOnLoad()가 필수적임.
            DontDestroyOnLoad(gameObject);
        }
    }
}

// AceUtils은 singleton으로 동작.
// 매번 할 때마다 위의 다른 예제들과 같은 구문 작성이 필요 없어짐.
public class AceUtils : SingletonMonobehaviour<AceUtils>
profile
복습하기 위해 쓰는 글

0개의 댓글

관련 채용 정보