이 글과 이후 글에서는 싱글턴에 대한 설명보다는 Unity에서 구현해보는데 집중해보고, 문제점과 해결방법을 이야기해볼 예정입니다.
싱글턴에 대한 좀 더 상세하고 원론적인 내용이 필요하신 분은 다른 글을 보시면 될 것 같습니다.
싱글턴(Singleton)이라고 하면 디자인 패턴(Design Pattern) 중, 정말 많이 쓰이는 패턴 중 하나입니다.
싱글턴 패턴은 클래스를 글로벌로 접근 가능하도록하는 방법 중 하나인데, 만들기도 간단하고 만들어두면 정말 편하게 사용 가능해서 여기저기 많이 쓰이는 패턴입니다.
public class ItemInventory
{
static ItemInventory m_Instance = null;
public static ItemInventory Instance
{
get
{
if (m_Instance == null) m_Instance = new ItemInventory();
return m_Instance;
}
}
public Item GetItem(int itemID) { /* ... */ }
public bool AddItem(Item item) { /* ... */ }
}
간단한 예제로 ItemInventory
라는 싱글턴 클래스를 만들어보았습니다.
static 변수로 클래스를 Instance
로 접근하도록 구현하면 됩니다.
//프로퍼티로 구현
static ItemInventory m_Instance = null;
public static ItemInventory Instance
{
get
{
if (m_Instance == null) m_Instance = new ItemInventory();
return m_Instance;
}
}
//readonly변수로 구현
public readonly static ItemInventory Instance = new ItemInventory();
//함수로 구현
static ItemInventory m_Instance = null;
public static ItemInventory GetInstance()
{
if (m_Instance == null) m_Instance = new ItemInventory();
return m_Instance;
}
저의 경우에는 프로퍼티를 좋아해서 프로퍼티로 구현했는데, 위 코드처럼 readonly변수로 Instance
를 선언하거나 프로퍼티 대신 함수로 구현해도 무방합니다.
var item = ItemInventory.Instance.GetItem(1000);
실제 호출되는 부분은 이렇게 Instance
로 접근해서 싱글턴 클래스의 맴버를 호출하면 됩니다.
public class SingletonTemplate<T> where T : class, new()
{
static T m_Instance = null;
public static T Instance
{
get
{
if (m_Instance == null) m_Instance = new T();
return m_Instance;
}
}
}
public class ItemInventory : SingletonTemplate<ItemInventory>
{
public Item GetItem(int itemID) { /* ... */ }
public bool AddItem(Item item) { /* ... */ }
}
추후에 재활용성을 고려하여 Template으로 구현한 예제입니다.
그렇게 긴 코드가 아니긴 하지만, 추후에 싱글턴에 기능이 더 추가되거나 싱글턴 클래스들의 관리가 필요할 경우 유용하게 쓰입니다.
Unity에서는 싱글턴 클래스가 MonoBehaviour
의 기능을 이용해야할 경우들이 존재하는데, 이러한 문제를 해결하기 위해 Unity에서 사용하는 싱글턴입니다.
public class MonoBehaviourSingletonTemplate<T> : MonoBehaviour where T : MonoBehaviour
{
static T m_Instance = null;
public static T Instance
{
get
{
if (m_Instance == null)
{
var obj = new GameObject(typeof(T).Name);
m_Instance = obj.AddComponent<T>();
}
return m_Instance;
}
}
protected void Awake()
{
DontDestroyOnLoad(gameObject);
}
}
MonoBehaviour
는 Unity에서 사용하는 Component
클래스이기 때문에, GameObject
에 AddComponent
함수로 추가하여 사용해야 합니다.
Instance
프로퍼티 내부 코드를 보시면 바로 아실 거라 생각됩니다.
아마도 다음 편에서 MonoBehaviour 싱글턴에 대해 좀 더 상세히 장단점을 다뤄볼 예정이긴 한데, 우선 이러한 싱글턴을 Unity에서 주로 사용되는 경우는 아래처럼 몇가지 상황을 위해 사용됩니다.
우선 이번 편에서 간단하게 싱글턴 클래스들을 만들어봤습니다.
사실 첫 글이라 어떻게 혹은 어떤 구성으로 쓰는 게 좋을지 고민하고 조사해보느라 시간이 너무 많이 소모되었던 것 같네요.
다음 편부터는 할 말이 정말 많아서 첫 편은 짧고 쉬운 소재로 골랐는데 글이 잘 쓰였을지 잘 모르겠네요.
길지 않은 글이였지만 봐주셔서 감사합니다.
정리를 너무나 상세하고 친절하게 해주셔서 뒤늦게 유니티 개발에 뛰어든 저에게 큰 도움이 되었습니다! 감사합니다 :)