디자인 패턴 : 싱글톤 패턴

김동현·2022년 7월 19일
0

디자인 패턴

객체지향 설계를 도와주기 위한 패턴
객체 지향 프로그래밍

객체로 프로그램을 제작한다.
객체 : 상태(데이터)(필드.변수)와 행동(기능)(메서드)을 가지고 있는 어떤한 것
구체적인것 추상적인것 다 가능
현실세계를 그대로 모델링 할 수 있다.
특징
- 추상화 : 일반적인 인터페이스를 정의하는 것
- 상속 : 코드를 물려받는 것. 즉 재사용할 수 있는 것
- 다형성 : 하나의 인터페이스로 다양한 동작을 할 수 있는 것
- 캡슐화 : 데이터와 함수를 함께 적을 수 있는 것
구조와 해결하자는 문제가 무엇인지 정확이 알고 써야 된다.

싱글톤 패턴(Singleton Pattern)

단일체

객체지향 버전의 전역변수를 만드는 것

오직 한개의 인스턴스만을 갖도록 보장하고, 이에 대한 전역적인 접근점을 제공하는 패턴

구현 : 추상클래스를 만들고 추상클래스를 상속받아 사용

C++에서의 탬플릿을 C#에선 제네릭 이라 불린다. 탬플릿보다 제네릭이 조금 더 자유도가 낮다.
제네릭 : C# 에서 지원하는 일반화 프로그래밍

장점 :
1. 인스턴스의 유일성을 보장한다
싱글톤 패턴은 인스턴스가 유일하도록 컴파일 단계에서 강제한다. 혹여 인스턴스의 개수를 늘리고자 할 때도 유연하게 바꿀 수 있다.

  1. 게으른 초기화(Lazy Initialization)가 일어난다.
    사용하지 않는다면 생성되지 않을 뿐더러 런타임에 초기화가 된다.

  2. 어디서든 쉽게 접근할 수 있다.
    전역적인 접근점을 제공하기 때문이다.

  3. 이름 공간을 좁힌다.
    전역 이른 공간 대신 클래스 이름 공간을 사용하기에 이름 공간이 더렵혀지는 것을 방지할 수 있다.

단점 :
1. 결국 전역 변수다.
전역 변수보다 조금 나은 부분이 있지만 결국 전역적인 접근점을 제공하기에 전역 변수와 같다. 전역 변수는 코드 간 결합도를 높이며, 유지보수를 어렵게 한다. 또한 스레드 동기화 문제가 있다.

  1. 게으른 초기화를 방지할 수 없다.
    초기화에 오랜 시간이 걸리거나, 메모리 단편화를 방지하기 위해 메모리 풀링(Memory Pooling)을 사용하는 경우 초기화 시점을 제어해야 한다. 하지만 싱글톤 패턴에서는 불가능하다.
  2. 두 가지 문제를 풀려고 한다.
    싱글톤 패턴은 인스턴스의 유일성도 보장함과 동시에 전역적인 접근점도 제공한다.

고려사항 :
1. 꼭 클래스가 필요한가?
2. 정적 변수를 이용해 인스턴스 개수를 제한할 수 있다.
3. 전역적인 접근점 대신에 다른 방법을 사용하자.

> 의존성 주입을 사용하자
> 상위 클래스를 이용하자
> 이미 전역인 객체를 이용하자
> 중재자 패턴을 사용하자
  1. 모노스테이트를 활용할 수도 있다.

컴포넌트 싱글톤 구현

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

    // template <typename T>
public class SingletonBehaviour<T> : MonoBehaviour where T : MonoBehaviour
    // where 는 T에 대한 컴포넌트 제약을 걸어주는것 제네릭에 사용하는것이다.
    // MonoBehaviour를 상속받는 것이여야만 한다.
{
    private static T _instance;

    public static T Instance 
    {
        get 
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<T>();
                DontDestroyOnLoad(_instance.gameObject);
            }

            return _instance; 
        } 
    }

    private void Awake()
    {
        if (_instance != null)
        {
            if (_instance != this)
            {
                Destroy(gameObject);
            }

            return;
            // 유일성 보장
        }
        _instance = GetComponent<T>();
        DontDestroyOnLoad(gameObject);
    }
    
}

이런식으로 사용할 수 있다.

디자인 패턴의 종류

생성 : 객체의 생성
추상 팩토리
빌터
팩토리 메서드
원형
단일체

구조 : 다향성을 확보할 수 있게 구조를 잡을 수 있는가
적응자
가교
복합체
장식자
퍼사드
플라이급
프록시

행동 : 동작에 관련된 부분
책임 연쇄
명령
해석자
반복자
중재자
메멘토
감시자
상태
전략
템플릿 메서드
방문자

profile
해보자요

0개의 댓글