싱글턴 패턴

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

언어별 구현 
 파이썬의 모듈은 그 자체로 싱글턴이다.
 자바는 생성자를 private으로 선언하여 상속이 불가능함을 지정하기도 한다.

자바 
public class Coin {

    private static final int ADD_MORE_COIN = 10;
    private int coin;
    private static Coin instance = new Coin(); // eagerly loads the singleton

    private Coin() {
        // private to prevent anyone else from instantiating
    }

    public static Coin getInstance() {
        return instance;
    }

    public int getCoin() {
        return coin;
    }

    public void addMoreCoin() {
        coin += ADD_MORE_COIN;
    }

    public void deductCoin() {
        coin--;
    }
}

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

파이썬 
class Singleton:
    __instance = None

    def __new__(cls, *args):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls, *args)
        return cls.__instance

C++ 
class Singleton {
 public:
  static Singleton& GetInstance() {
    // Allocate with `new` in case Singleton is not trivially destructible.
    static Singleton* singleton = new Singleton();
    return *singleton;
  }

 private:
  Singleton() = default;

  // Delete copy/move so extra instances can't be created/moved.
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;
  Singleton(Singleton&&) = delete;
  Singleton& operator=(Singleton&&) = delete;
};

C# 
public sealed class Singleton
{
    private static volatile Singleton? _instance;
    private static readonly object _lock = new object();

    private Singleton() { }

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

            lock (_lock)
            {
                if (_instance == null)
                    _instance = new Singleton();
            }

            return _instance;
        }
    }
}

public static class Singleton
{
    public static MyOtherClass Instance { get; } = new MyOtherClass();
}

유니티 
class Singleton : MonoBehaviour
{
    public static Singleton Instance { get; private set; }

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            Instance = this;
        }
    }
}

다트 
class Singleton {
    Singleton._();
    static Singleton get instance => Singleton._();
}

PHP 
class Singleton
{
    private static $instance = null;

    private function __construct() {}

    public static function getInstance(): self
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

코틀린 
object Coin {
    private var coin: Int = 0

    fun getCoin():Int {
        return coin
    }

    fun addCoin() {
        coin += 10
    }

    fun deductCoin() {
        coin--
    }
}

파스칼 
unit SingletonPattern;

interface

type
  TTest = class sealed
  strict private
    FCreationTime: TDateTime;
  public
    constructor Create;
    property CreationTime: TDateTime read FCreationTime;
  end;

function GetInstance: TTest;

implementation

uses
  SysUtils
  , SyncObjs
  ;

var
  FCriticalSection: TCriticalSection;
  FInstance: TTest;

function GetInstance: TTest;
begin
  FCriticalSection.Acquire;
  try
    if not Assigned(FInstance) then
      FInstance := TTest.Create;

    Result := FInstance;
  finally
    FCriticalSection.Release;
  end;
end;

constructor TTest.Create;
begin
  inherited Create;
  FCreationTime := Now;
end;

initialization
  FCriticalSection := TCriticalSection.Create;

finalization
  FreeAndNil(FCriticalSection);

end.

Go 
package main

type Singleton struct {}

var instance *Singleton

func GetInstance() *Singleton {
	if instance != nil {
		return instance
	}
	instance = new(Singleton)
	return instance
}

같이 보기 
 전역 변수

소프트웨어 디자인 패턴
안티패턴