싱글톤 패턴(Singleton Parttern)

장상희·2024년 12월 9일

1.싱글톤 패턴의 개념 및 원리

  • 하나의 클래스에서 단 한의 인스턴스만 존재하게 하는 패턴

싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. 주로 공통된 객체를 여러개 생성해서 사용하는 DBCP(DataBase Connection Pool)와 같은 상황에서 많이 사용된다.

(하나의 인스턴스만 필요 할떄 유용하게 사용할 수 있는 디자인 패턴이고 게임개발에서 자주 사용할 수 있다 주로 게임의 전반적인 상태나 설정들을 관리하는 매니저 클래스 리소스를 관리하는 그런 객체들을 싱글톤 패턴으로 관리한다(사용하기는 편리한데 무분별하게 사용하면 코드가 점점 의존적으로 엮이게 되고 유지 보수가 힘들어 질 수 있다) )

2. 가장 일반적인 싱글톤 구현 방법

//즉시 초기화 싱글톤
private static Singleton instance = new Singleton();//만들긴 했지만 외부에서 접근이 안된다
public static Singleton Instance {get{return instance;}}//접근하기 위해서는 public으로된 Instance로 해서 리턴하면 위 인스턴스에 접근할 수 있다
private Singleton() { }// 외부에서는 더 이상 new키워드를 이용해서 새로운 인스턴스를 만들지 못하게 하기위해서 Private하고 생성자를 만들어 주면 이제 외부에서는 싱글톤의 인스턴스를 만들지 못한다

public void Test() => Debug.Log("Test")

public void Awake()
{
	Singleton.Instance.Test();
}

이 방식은 즉시 초시화 싱글턴이라 할 수 있다 인스턴스를 미리 생성하는 방식이다 우리가 만든 인스턴스를 접근하기 위해서는 프로퍼티를 통해서만 접근이 가능하다 그렇기 때문에 단 하나의 인스턴스를 만드는 방식이고 그게 바로 싱글톤이고 지금 이거는 단 하나의 인스턴스를 만들었지만 시작하자 마자 필드에 만들었기 때문에 즉시 초기화 싱글톤이라 부른다

3.게으른 싱글톤 구현

//게으른 초기화 싱글톤
private static Singleton instance;
public static Singleton Instance
{
	get
	{
		if(instance == null)
			instance = new Singleton();
			
		return instance;
	}
}
private Singleton() { }

public void Test() => Debug.Log("Test")

public void Awake()
{
	Singleton.Instance.Test();
}

게으른 초기화 싱글턴: 인스턴스를 미리 생성하는 방식

게으른 싱글턴은 언제 생성하냐 하면 외부에서 사용할때 인스턴스 변수에 접근하니깐 이때 get해서 인스턴스가 null이면 그떄 new해서 새로운 인스턴스를 생성해줍니다 인스턴스를 생성했으니깐 테스트 메소드를 사용할 수 있다 그다음 접근할때는 이미 이렇게 생성을 했으니깐 그다음에는 그냥 바로 리턴해서 인스턴스에 접근해서 바로 사용할 수 있다

4.두 싱글턴의 차이점

게으른 싱글턴은 즉시 초기화 싱글턴과 다르게 시작하자 마자 new해서 새로운 인스턴스를 생성하지 않는다 그럼 두 방식의 차이점은 즉시 초기화 싱글턴은 시작하자 마자 싱글턴을 만들기 때문에 메모리 적으로 봤을때는 프로그램상 메모리가 싱글턴이 바로 올라가 있을 수 밖에 없다 하지만 게으른 싱글턴은 나중에 필요할 때 싱글턴을 생성하기 때문에 메모리 부담이 적을 수 밖에 없다 그래서 성능으로 보면 게으른 싱글턴이 조금 더 낫다 하지만 싱글턴 하나 두 개 더 있다 해서 큰 차이는 없지만 굳이 나누자면 이런식의 차이가 있다

//하지만 Unity는 MonoBehavour을 상속 받기 때문에 큰 차이점이 있다

5. 유니티에서 싱글톤 구현방법

  • MonoBehaviour

-유니티에서는 일반적인 싱글톤 구현방법하고 차이가 있습니다

private static Singleton instance;
public static Singleton Instance {get{return instance;}}
publiv void Awake() //이메소드는 씬이 로드될때 자동으로 호출된다
{
	if(instance == null)//인스턴스가 널이면 this에서 자기 자신의 인스턴스를 넣어 줄꺼다
	{
		instance = this;
		DontDestroyOnLoad(gameObject);//이 스크립트는 게임오브젝트에 부착할 스크립트니깐 이런식으로 하면 씬이 이동이 되더라고 그 게임오브젝트는 파괴 되지 않는다
		
	}
	else//인스턴스가 넣이 아니라는건 이미 인스턴스가 하나 있다는 거고 게임오브젝트에 해당 싱글턴이 붙어 있다는거니깐 나머지는 삭제하겠다는 간단한 코드
	{
		Desstroy(gameobject);
	}
}

5-1. MonoBehaviour

MonoBehaviour을 상속 받은 스크립트는 항상 게임오브젝트의 구성 요소로만 존재한다고 한다 결국에는 MonoBehaviour를 상속받은 스크립트들은 게임오브젝트에다가 AddComponent해서 붙일꺼니깐 그 자체가 인스턴스라 인식하면 된다

5-2 유니티로 구현하는 게으른 싱글턴

private static Singleton instance;
public static Singleton Instance
(
	get
	{
		if (instacne == null)
		{
			Setupinstance();
		}
		return instance;
	}
}

private static void SetupInstance()
{
	instance = FindObjectOfType<Singleton>();//하이얼 락키 창에 있는 모든 타입을 검사한다 싱글턴으로 만들 타입을 검사를 해서 그 타입을 인스턴스에 가져온다
//	타입이 있으면 가져오고 만약 null이면 새로운 게임오브젝트를 만들고 해당 타입의 이름을 그게임 오브젝트의 네임에 넣어줄꺼다 그리고 만든 게임오브젝트를
//	 게임오브젝트에 AddComponent해서 그 타입을 붙여줄꺼고요 그걸 바탕으로 인스턴스를 바로 뽑아 줄수 있다 그리고 씬이 이동되도 파괴되지 않도록 DontDestroyOnLoad(gameObj) 로 감싸준다 )
// 그러면 이젠 이 인스턴스가 게임오브젝트도 자동으로 만들어지고 여기에 AddComponent해서 인스턴스로 보내졌으니깐 해당 타입을 가지고 있을테고 결국에는 리턴해서 해당 인스턴스를 사용할 수 있을 거다
	if (instance == null)
	{
		GameObject gameObj = new GameObject();
		gameObj.name = typeof(Singleton).Name;
		instance = gameObj.AddComponent<Singleton>();
		DontDestroyOnLoad(gameObj);
	}

기존 싱글턴과 유니티 싱글턴의 차이점

기존 싱글턴은 뉴키워드를 이용해서 만들었다면 MonoBehaviour 상속받는 순간 뉴키워드는 추천 하지 않기 때문에 새로운 메소드를 만들었다

profile
프로그래머 꿈나무

0개의 댓글