싱글톤(Singleton) 디자인 패턴은 게임 개발 시 단 하나의 유일한 인스턴스만 존재해야 하는 Manager 클래스 들을 구현하기 위해 가장 많이 사용되는 디자인 패턴이다.
개발 언어, 플랫폼과 관련없이 싱글톤 패턴은 언제 어디에서 호출 하든 동일한 인스턴스의 응답을 보장하기 위해 static 키워드를 사용하여 첫 호출 시 동적 할당한 자신의 인스턴스를 담아 게임이 종료 되는 순간까지 유지하는 방식으로 구현하게 된다.
(다만, 유니티는 모든 GameObject가 MonoBehaviour 클래스를 상속받기 때문에 주의할 점이 있다.)
SoundManager, NetworkManager, DataManager, CharacterManager, PopupManager, StageManager, GameManager, SceneManager 등등 게임 마다 다양한 종류의 매니저 클래스를 필요로 하는데 모든 클래스마다 이런 동적 할당 및 체크 하는 로직을 매번 타이핑 하는 것은 매우 비생산적인 작업일 것이다.
그러므로 이 포스팅에서는 제너릭(Generic) 클래스를 기반으로 매니저 클래스에 싱글톤 패턴의 로직을 손쉽게 상속받아 사용하는 방법을 알아본다.
Generic 기반의 클래스 생성을 위해 Singleton<T> : MonoBehaviour where T : MonoBehaviour 로 클래스를 생성한다.
이렇게 함으로써 각기 다른 매니저 클래스를 만들 때에도 손쉽게 싱글톤 생성 및 체크 로직을 사용할 수 있게 된다.
사용하는 방법은 매우 간단하다.
public class NetworkManager : Singleton <NetworkManager>
{
protected NetworkManager()
{
}
}
Singleton 클래스를 상속 받고 자신의 클래스를 템플릿으로 넘겨주면 끝이다.
싱글톤 자체가 수행할 처리 들은 템플릿으로 매니저 클래스를 넘겨 받은 Singleton 클래스가 알아서 처리해 준다.
본문의 주석에도 있듯이 싱글톤에서 상속받은 생성자 외에 비 싱글톤 생성자 사용을 막기 위해 protected 로 미리 생성자를 선언해 두면 안전하다.
코드상에 몇가지 주목할 부분이 있다.
MonoBehaviour 에서 상속을 받았기 때문에 라이프 사이클에 따라 게임 종료 명령 후 타이밍에 따라 해당 매니저 클래스가 호출 되는 상황을 막기 위해 _ShuttingDown 변수를 이용, null 을 리턴한다.
즉, 매니저 호출 시 특히 OnDestroy 등에서 데이터를 초기화 하기 위해 호출할 때는 필수로 null 체크를 해주는 것이 좋다.
또한 DontDestroyOnLoad 함수로 싱글톤 오브젝트 객체를 등록하기 때문에 게임 내에서 씬 이동을 해도 인스턴스가 유지된다.
댓글