デザインパターン「Singleton」

# はじめに
本投稿は<a href="http://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80" target="_blank">Java言語で学ぶデザインパターン入門</a>のデザインパターンをまとめた記事です。今回はSingletonパターンになります。
[まとめ一覧はこちら](#design_pattern)

# Singletonパターン
<p align="center"><img width="442" alt="スクリーンショット 2016-02-14 15.31.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/7e3c6acd-ac33-9551-1262-dbb2ca3a60ae.png"></p>

## Singletonパターンとは

一言でいうと、生成するインスタンスの数を1つに制限するデザインパターンです。

- 指定したクラスのインスタンスが***1つしか存在しないことを保証する***
- インスタンスが1個しか存在しないことをプログラム上で表現したい

このような場合にSingletonパターンを用いてインスタンスを生成します。
インスタンスの状態を保持したかったり、クラス間で共通のメソッド・プロパティにアクセスしたい場合に使われることが多いですね。


## Singletonパターンのクラス図
<p align="center"><img width="300" alt="スクリーンショット 2016-02-14 15.53.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/aefa38aa-6911-ab86-3813-286c06b57416.png"></p>

- クラス変数としてsingletonを定義
- インスタンスを得るためのstasticメソッドで同じインスタンスを返す

## 具体例
生成したインスタンスが同一かどうか簡単な例で確かめてみましょう。

### <a id="main">Mainクラス</a>

以下のように`getInstance()`によって得たインスタンスが同一のものか確かめてみます

```java:Main.java
public static void main(String[] args) {
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		
		if (instance1 == instance2) {
			System.out.println("instance1 and instance2 are same Instance");
		} else {
			System.out.println("instance1 and instance2 aren't same Instance");
		}		
}
```

### Singletonクラス

```java:Singleton.java
public class Singleton {
	
    //①
	private static Singleton singleton = new Singleton();
    //②
	private Singleton() {
		System.out.println("Cretae Instance");
	}
    //➂
	public static Singleton getInstance() {
		return singleton;
	}
}
```

Singletonパターンを適応するにあたり、以下のルールに準拠する必要があります

- ①自身の型のインスタンスが privateなクラス変数として定義されている
- ②外部から生成されないようにprivateにしている
- ➂インスタンスを返すためのクラス関数が定義されている

①のstaticフィールドによってクラス初期化時に唯一のインスタンスが生成されるので、どこからでも参照できるグローバル領域で管理されるんですね。

## 実行結果

```java
Cretae Instance
instance1 and instance2 are same Instance
```
一回のみコンストラクタが呼ばれていますね。

[Mainクラス](#main)でテストしたように、Singletonクラスは利用する側からは

- newできない
- 同一なオブジェクトが返される

クラスであると言えます


## マルチスレッドに対応した例
実際のシステムでは複数のスレッドに同時にアクセスする場合があり、想定しないインスタンスが生成される場合があります。
その場合は、インスタンスを返す`getInstace()`のメソッドを`synchronized`指定し、同期処理をさせる必要があります。

```java:Singleton.java
class Singleton {
	static Singleton instance = null;
	public static synchronized Singleton getInstace() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}
```

この場合は、同期処理による処理速度の低下を考慮する必要があります。

##### 2016/11/4更新

現在ではこのような記述が推奨されているようです。

###### @sipadan2003 さんご教授ありがとうございます。

```java
class Singleton {
    private Singleton(){}

    public static Singleton getInstace() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
}

```

1. Singletonクラスがロードされた時点では、Singletonインスタンスは生成されない
2. Singleton#getInstance()を最初に呼び出した時に、SingletonHolderクラスがロードされ、Singletonインスタンスが生成される

synchronizedを使用することなく、ギリギリまでSingletonインスタンスを生成しないような挙動になるようです。

## iOS(Objective-C)の場合

```objc:Singleton.m
@implementation Singleton

static Singleton *sharedInstance = nil;

+ (Singleton *)getInstace
{
    @synchronized(self){
        if (!sharedInstance) {
            sharedInstance = [Singleton new];
        }
    }
    return sharedInstance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        //初期化処理
    }
    return self;
}
```

Objective-Cの場合も`@synchronized`用いてスレッドセーフな記述が可能です。
また、`dispatch_once_t`を用いた記述も可能ですが、

```objc
- (void)destructor
{
    sharedInstance = nil;
}
```
のようなSingleton解放の処理はできないようなので`@synchronized`用いたスレッドセーフな記述が良さそうです

参照: <a href="http://qiita.com/yuky_az/items/27031ec5ca55a95d6209" target="_blank">iOSのシングルトンの話</a>


# 追記
- Javascriptの場合は、オブジェクト全てがSingletonとみなされる
 - 参照: <a href="http://qiita.com/KENJU/items/54760d292d8fbddb1015" target="_blank">【JSでデザインパターン】シングルトン編</a>
- Singletonの別の方法として、Monostateパターンもある
 - 参照: <a href="http://hamasyou.com/blog/2004/07/23/monostate/" target="_blank">実践デザパタ-その13:Monostateパターン</a>


### 問題点
<dl>
 <dt>Singletonクラスを明示的に開放するための機能がない、もしくは自作で適切なタイミングで解放する必要がある</dt>
 <dd>詳細: <a href="http://qiita.com/kikuuuty/items/fcf5f7df2f0493c437dc" target="_blank">シングルトンのベターな実装方法</a></dd><br>
 <dt>クラス間の依存関係や状態が一見してわからないので、コードから推測するのが困難</dt>
 <dd>ユニットテストのモック運用や状態設定が困難になる</dd>
</dl>

### サンプルコードについて

以下のレポジトリにソースコードをアップしてあります。

[shoheiyokoyama/design-pattern_java](https://github.com/shoheiyokoyama/design-pattern_java/tree/master/Singleton)

# <a id="design_pattern">デザインパターン</a>
- 生成に関するパターン
 - Abstract factory
 - Builder
 - <a href="http://qiita.com/shoheiyokoyama/items/d752834a6a2e208b90ca" target="_blank">Factory Method</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/61826e158b3c4a259065" target="_blank">Prototype</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/c16fd547a77773c0ccc1" target="_blank">Singleton</a>
- 構造に関するパターン
 - <a href="http://qiita.com/shoheiyokoyama/items/bd1c692db480b640c976" target="_blank">Adapter</a>
 - Bridge
 - Composite
 - Decorator
 - Facade
 - Flyweight
 - Proxy
- 振る舞いに関するパターン 
 - Chain of responsibility
 - Command
 - Interpreter
 - <a href="http://qiita.com/shoheiyokoyama/items/3f42d0057d9d5a861039" target="_blank">Iterator</a>
 - Mediator
 - Memento
 - <a href="http://qiita.com/shoheiyokoyama/items/d4b844ed29f84a80795b" target="_blank">Observer</a>
 - State
 - Strategy
 - <a href="http://qiita.com/shoheiyokoyama/items/c2ce16b4f492cd014d50" target="_blank">Template Method</a>
 - Visitor

# 参考文献
- <a href="http://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80" target="_blank">Java言語で学ぶデザインパターン入門</a> 
- <a href="http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html" target="_blank">サルでもわかる 逆引きデザインパターン</a>
- <a href="http://qiita.com/kikuuuty/items/fcf5f7df2f0493c437dc" target="_blank">シングルトンのベターな実装方法</a>
- <a href="http://qiita.com/yuky_az/items/27031ec5ca55a95d6209" target="_blank">iOSのシングルトンの話</a>