[디자인 패턴] 싱글톤 패턴
in Unity
디자인 패턴 중 하나인 싱클톤 패턴에 대해서 간단하게 설명하겠다.
싱글톤 패턴
싱글톤 패턴이란 게임상에서 단 하나만 존재해야하는 객체가 있고, 그 객체는 어디서든 쉽게 접근이 가능해야 한다는 목적성이 있을 때 사용이 된다. 예를 들면 프로그램의 전반적인 시스템을 관리하는 시스템 매니저같은 클래스처럼 단 하나만 존재해야 하는 클래스를 만들 때 사용된다.
예시 코드를 보자 안에 설명까지 되어 있다.
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 오브젝트를 할당하고 이미 할당이 되어있으면 싱글톤이 될 수 없는 자신의 게임오브젝트를 파괴한다.
장점
이렇게 싱글톤 패턴을 구현하면 게임상에서 단 하나만 존재해야 하는 객체의 유일성을 보장하고 어디서나 쉽게 접근하게 할 수 있다.
단점
어디서나 쉽게 접근이 가능하다고 해서 남발하게 되면 나중에 코드를 해석할 때 오히려 더 복잡해 지는 경우가 있을 수 있으니 꼭 필요한 대상에 대해서만 사용하는게 올바르다.