컴퓨터/정보처리기사 SW 공학

| 니앙팽이 - 객체지향(OOP) | 4-2 | 생성패턴 - Singleton pattern

객체지향

📕 4. 객체지향 디자인 패턴

유니티에서 사용하면 좋을 디자인 패턴만 명시한다.


📄 3. 생성 패턴

생성과 참조과정을 캡슐화 하여 객체가 생성되거나 변경되도
시스템에 영향을 크게 받지 않도록 프로그램의 유연성을 더해주는 패턴


1). Singleton pattern

ⓔ 구성요소

  1. Application : 싱글톤에 접근하는 어떠한 아~무 코드
  2. Singletion :
    • private로 싱글톤 인스턴스가 클래스 내부에 포함된다.
    • GetInstance() 로 싱글톤 인스턴스를 static으로 접근한다.

ⓐ 특징

  1. 전역적으로 접근 가능한 객체라 어디에서든지 참조할 수 있다.
  2. 인스턴스가 오직 단 하나를 상성함을 보장, 불필요한 메모리 낭비를 최소화 할 수 있다


1. 인스턴스가 하나만 있다. 2. 어디서든 문을 열수있다(어디서든 접근 가능)

  1. 너무 남용하면 다른 클래스의 인스턴스들 간에 결합도가 높아져 개방 폐쇠 원칙이 위배될 수 있다.

ⓑ 사용하는 이유

  • 전역적으로 사용되는 데이터, 리소스를 수시로 접근해야 할때

  • GameManager 힘들게 지정하는 대신 쉽게 Static으로 접근 가능

ⓒ 다음과 같은 목적에 사용하기를 권한다.

1. 환경설정 : Audio Manager
2. Save & Load : 단 동기화 문제가 없을시.
3. Camera : 이미 유니티에 Camera.main으로 구현되어있음
4. EventSystem : 사실 이미 유니티에 구현되어 있음
5. Pool : 싱글톤 GameObject를 생성해서 사용. 
  GameLoop가 없는 객체로만.

ⓓ 사용해서는 안되는 상황

1. 플레이서, 몹, 이펙트
개발 과정에서 결합도가 높아지는 경우가 있음
게다가 Static 변수는 어디서 일어난 버그인지 디버깅 트랙하기 힘들다. 

ⓕ 예시

1. 동시성 문제 : 하나만 있어야할 싱글톤 객체가 두번 생성될 수 있는 문제.

  • 싱글톤 생성이 느리면 모든 쓰레드가 거의 동시에 도착하고 이로인해 서로가 null 객체를 바라볼수 있다.
  • 해결책 : Thread-Safe 가 보장되어야 한다.
📂Lazy 기법을 이용한 싱글톤📂
public class LazySingleton {
    private static readonly Lazy<LazySingleton> _instance
        = new Lazy<LazySingleton>(() => new LazySingleton());

    public static LazySingleton Instance {
        get { return _instance.Value; }
        // _instance는 Lazy 객체 이므로 실제 인스턴스는 Value에 있다. 
    }
    private LazySingleton() { }
}

2. 프레임 드랍 문제

  • 필요할 때 초기화하는 Lazy 기법. 하지만 전투 도중에 시스템 초기화 작업을 수행한다면 중간에 프레임이 떨어지거나 게임 화면이 뚝뚝 끊길 수도 있다.
  • 해결책 : 게임 플레이에 영향이 미치지않도록 시작과 동시에 정적 변수를 초기화
📂일반적인 싱글톤 & 오브젝트 풀📂
// 일반적인 싱들톤
public class Singleton {
    private static readonly Singleton _instance = new Singleton();

    public static Singleton Instance {
        get {
            if(_instance == null) return new Singleton();
            return _instance;
        }
    }
}

//GameObject로 사용
public class _className_ : MonoBehavier {
    private static _className_ _instance;

    public static _className_ Instanace {
        get{
            if(_instance == null){ 
                var obj = FindObjectType<_classNmae_>();
                if(obj != null){_instance = obj;}
                else if(obj == null) {
                    var newObj = new GameObject().AddComponent<_className_>();
                    return _instance;
                }
            }
        }
        private set;
    }
}

참고

  1. https://csharpindepth.com/articles/singleton
  2. 싱글톤 개요
  3. 싱글톤 c#
  4. 싱글톤 c#
  5. Master Singleton: in unity the right way
  6. Master Singleton Video