유니티 게임 팀 프로젝트를 진행하던 중 Manager들은 싱글톤을 처리 하는 경우가 많았습니다.
그런데 팀원마다 담당한 파트가 다르고 각자의 스타일로 싱글톤 코드를 작성해서 진행했습니다.
그러던 중 반복적으로 작성하는 싱글톤 코드를 통합 시켜 처리할 방법은 없을까 고민했습니다.
그 결과 싱글톤을 제네릭 클래스로 만들어 상속 받아서 사용하는 방법을 찾게 됩니다.
using UnityEngine;
public class CustomSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T m_Instance;
public static T Instance
{
get
{
if (m_Instance == null)
{
m_Instance = (T)FindObjectOfType(typeof(T));
if (m_Instance == null)
{
GameObject singletonObject = new GameObject { name = "@" + typeof(T).ToString() };
m_Instance = singletonObject.AddComponent<T>();
DontDestroyOnLoad(singletonObject);
}
}
return m_Instance;
}
}
}
위 싱글톤 코드의 특징을 정리해봤습니다.
Manager에 적용한 예시
public class GameManager : CustomSingleton<GameManager>
{
private void Awake()
{
// ....
}
private void Update()
{
// ....
}
}
사용 방법은 상당히 간단합니다.
구현해 놓은 제네릭 싱글톤 클래스를 상속 받고, 싱글톤 클래스명을 제네릭 T에 적으면 됩니다.
제네릭 싱글톤 코드에서 T 라고 적혀 있는 부분은 제네릭 문법에서 사용하는 방법입니다.
프로젝트를 진행하면서 다른 팀원들도 잘 활용하고 유용했던 싱글톤 처리 방법이였습니다.
하지만 우려되는 점은 누군가 싱글톤 제네릭 클래스를 수정하면, 상속 받은 모든 클래스에 영향을 줄 수 있는다는 점입니다.
그리고 어떤 제네릭 싱글톤 클래스를 보면 동시성 이슈를 방지하기 위해 Lock을 사용한 코드도 봤습니다.
기존 제네릭 싱글톤 클래스를 변경을 하지 않더라도 또 다른 제네릭 싱글톤 클래스를 만들면 그것 또한 문제가 될 것 같습니다.
이런 문제를 방지하기 위해 팀원과 사전에 소통을 하고 규칙을 정하거나 수정을 못하게 하는 방법도 고안해야 겠다고 생각했습니다.