싱글턴 패턴

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

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

### 자바

```java
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--;
    }
}
```



```java
public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

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


### 파이썬

```python
class Singleton:
    __instance = None

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


### C++

```cpp
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#

```csharp
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;
        }
    }
}
```



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


### 유니티

```csharp
class Singleton : MonoBehaviour
{
    public static Singleton Instance { get; private set; }

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


### 다트

```dart
class Singleton {
    Singleton._();
    static final Singleton _instance = Singleton._();
    static Singleton get instance => _instance;
}
```


### PHP

```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;
    }
}
```


### 코틀린

```kotlin
object Coin {
    private var coin: Int = 0

    fun getCoin():Int {
        return coin
    }

    fun addCoin() {
        coin += 10
    }

    fun deductCoin() {
        coin--
    }
}
```


### 파스칼

```delphi
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

```go
package main

type Singleton struct {}

var instance *Singleton

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


## 같이 보기
* 전역 변수

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