【Java】Singletonパターン

はじめに

オブジェクトを1つしか生成しないことを保証する手法としてシングルトンパターンが知られている。
今回は、シングルトンの概要と実装方法について述べる。

シングルトンって何ぞや?

ひとことで言うなれば、「オブジェクトを1つしか生成しないことを保証するための仕組み」である。
オブジェクトが生成される数に制限をかけたい場合があったとき、シングルトンを使うことで、複数のインスタンスを生成されなくすることができる。
ただ、オブジェクトの内容が他処理で書き換えられている可能性があるという側面も持ち合わせるため、シングルトンを使うときはその点に注意する必要がある。これについては、後述するサンプルコードで述べる。

シングルトンパターン実装方法

シングルトンのインスタンス生成方法のポイントは以下の点である。

(I)  唯一のインスタンスを「private static」として宣言する。
     →クラスが読み込まれたときに最初に一度だけ初期化される。

(II)  コンストラクタは「private」にする。
     →privateにしないと、newされて単一のインスタンスを生成できない。

(III) インスタンスはstaticメソッドを通してのみ受け取れるようにする。
     →クライアント側は、コンストラクタを使ってオブジェクトを生成しない。

public class MySingletonClass {

	private String str = "Hello";
	private static MySingletonClass instance = new MySingletonClass();     //ポイント (I)

	private MySingletonClass() {                                           //ポイント (II)
		// Constructor
	}

	public static MySingletonClass getInstance() {                         //ポイント (III)
		return instance;
	}

	public void setString(String str) {
		this.str = str;
	}

	public String getString() {
		return str;
	}
}

クライアント側は、staticメソッドであるgetInstanceを通してのみ、このクラスのインスタンスを取得することができる。
newしてインスタンス生成することはできない。なぜなら、コンストラクタはprivateだから。

クライアント側のプログラムを以下のように記述する。

public class Main {

	public static void main(String[] args) {
		MySingletonClass c1 = MySingletonClass.getInstance();
		MySingletonClass c2 = MySingletonClass.getInstance();

		System.out.println("c1 hashCode: " + c1.hashCode());
		System.out.println("c2 hashCode: " + c2.hashCode());
	}
}

実行結果は以下の通り。

c1 hashCode: 780173189
c2 hashCode: 780173189

2つのハッシュコードが同じであることが分かる。
つまり、「それぞれは同じオブジェクトを参照している」ことを意味している。

なので、例えば、c1のsetStringを実行してMySingletonClassのフィールドstrの値を書き換えた後に、c2のgetStringを実行すると、実行結果として、"Hello"でなく、setStringを実行して書き換わったフィールド値が表示される。

以下のようにクライアント側を実装して実行すると、コンソール上には"Hey!"が2つ表示される。

public class Main {

	public static void main(String[] args) {
		MySingletonClass c1 = MySingletonClass.getInstance();
		MySingletonClass c2 = MySingletonClass.getInstance();

		c1.setString("Hey!");

		System.out.println(c1.getString());
		System.out.println(c2.getString());
	}
}

おわりに

シングルトンパターンについて述べた。また、シングルトンをどのように実装するかをサンプルコードを交えて述べた。
シングルトンパターンとは、生成されるオブジェクトが1つだけであることを保証するパターンである。
シングルトンのオブジェクトを生成するためのポイントは以下の3点である。

(I)  唯一のインスタンスを「private static」として宣言する。
(II)  コンストラクタは「private」にする。
(III) インスタンスはstaticメソッドを通してのみ受け取れるようにする。

参考
JavaTips 〜Javaプログラミング編:クラスのインスタンスを1つに保つ(Singletonパターン) - @IT
矢沢久雄の早わかりGoFデザインパターン - 矢沢久雄の早わかりGoFデザインパターン(7):ITpro
サルでもわかる 逆引きデザインパターン 第2章 逆引きカタログ ロジック編 Singleton(シングルトン)