[디자인 패턴] 싱글톤 패턴



디자인 패턴 중 하나인 싱클톤 패턴에 대해서 간단하게 설명하겠다.

싱글톤 패턴

싱글톤 패턴이란 게임상에서 단 하나만 존재해야하는 객체가 있고, 그 객체는 어디서든 쉽게 접근이 가능해야 한다는 목적성이 있을 때 사용이 된다. 예를 들면 프로그램의 전반적인 시스템을 관리하는 시스템 매니저같은 클래스처럼 단 하나만 존재해야 하는 클래스를 만들 때 사용된다.

예시 코드를 보자 안에 설명까지 되어 있다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonComponent1 : MonoBehaviour
{
    //static으로 선언하게 되면 SingletonComponent1의 객체가 여러개여도 
    //instance 이 변수는 단 하나만 존재하게 된다.(정적변수의 특징)
    //private으로 설정한 이유는 외부에서 함부로 수정할 수 없게 하기 위함(유일성 확보)
    private static SingletonComponent1 instance;
    public static SingletonComponent1 Instance
    {
        get
        {
            if(instance == null) //만약 instance가 비어있으면
            {
                //씬 안에 SingletonComponent1를 가지고 있는 오브젝트가 있는지 검사
                var obj =FindObjectOfType<SingletonComponent1>();
                if (obj != null) //만약 있다면 그 오브젝트를 반환하고
                {
                    instance = obj;
                }
                else //없다면
                {
                    //새로운 게임 오브젝트를 만들고 거기다 SingletonComponent1를 부착해서 반환
                    var newObj = new GameObject().AddComponent<SingletonComponent1>();

                    instance = newObj;
                }
            }
            return instance;
        }
    }
    //유니티에서는 AddComponent나 SingletonComponent1가 이미 붙어있는 프리펩을 생성하는 막을 방법이 없다
    //그래서 객체가 생성되고 나서 중복검사를 하고 중복이 되어 있다면 그 오브젝트를 파괴하는 식으로 동작해야한다.
    private void Awake()
    {
        //씬에 같은 컴포넌트를 가진 게임 오브젝트가 총 몇 개 있는지 검사한다.
        var objs = FindObjectsOfType<SingletonComponent1>();
        if (objs.Length != 1) //만약 SingletonComponent1를 가지고 있는 오브젝트가 1개가 아니라면
        {
            Destroy(gameObject); // 이 오브젝트를 파괴한다.
            return;
        }
        //씬이 바뀌어도 싱글톤패턴이 적용된 객체가 파괴되지 않도록 
        DontDestroyOnLoad(gameObject);
    }
}

싱글톤 패턴은 위와 같이 정의가 가능하다. 코드를 해석하면 알겠지만 객체가 단 하나만 존재하게 설계 되어있고, 어디서나 쉽게 접근이 가능하도록 static으로 선언이 되어있다.

그리고 게임 매니저 같이 게임 안에서 하나만 존재해야 하는 오브젝트가 있다고 가정하고 코드를 작성해보겠다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public GameManager instans; //싱글톤을 할당할 변수

    private void Awake()
    {
        if(instans == null)
        {
            instans = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

우선 싱글톤을 할당할 변수를 static으로 선언하고 Awake함수에서 instance가 비어있는지 확인하고 비어있으면 GameManager 오브젝트를 할당하고 이미 할당이 되어있으면 싱글톤이 될 수 없는 자신의 게임오브젝트를 파괴한다.

장점

이렇게 싱글톤 패턴을 구현하면 게임상에서 단 하나만 존재해야 하는 객체의 유일성을 보장하고 어디서나 쉽게 접근하게 할 수 있다.

단점

어디서나 쉽게 접근이 가능하다고 해서 남발하게 되면 나중에 코드를 해석할 때 오히려 더 복잡해 지는 경우가 있을 수 있으니 꼭 필요한 대상에 대해서만 사용하는게 올바르다.




© 2022. by KSC

Powered by sora