はじめに
本エントリーは某社内で実施するデザインパターン勉強会向けの資料となります。
本エントリーで書籍「Java言語で学ぶデザインパターン入門」をベースに学習を進めますが、サンプルコードはC#に置き換えて解説します。
第1回:Iteratorパターン
第2回:Adapterパターン
第3回:Template Methodパターン
第4回:Factory Methodパターン
Singletonパターンとは
指定したクラスのインスタンスが1つしか存在しないことを保証するデザインパターンです。
サンプルプログラムのクラス図
Singletonパターンを使用したサンプルプログラムのクラス図を紹介します。
各クラスの役割
クラス名 | 役割 |
---|---|
Singleton | インスタンスが1つしか存在しないクラス |
ConfirmSingleton | 動作テスト用のクラス |
Singletonクラス
Singletonクラスでは、インスタンスは1つしか作られません。
Singletonクラスでは、staticフィールド(クラス変数)として_singletonが定義され、それをSingletonクラスのインスタンスで初期化しています。この初期化はSingletonクラスのロード時に1度だけ行われます。
Singletonクラスのコンストラクタはprivateになっています。
これはSingletonクラス外からコンストラクタを呼び出すことを禁止するためです。
したがって、もし、
new Singleton()
という式がこのクラス外にあったとしてもコンパイルエラーとなります。
using System;
namespace SingletonSample
{
public class Singleton
{
private static Singleton _singleton = new Singleton();
private Singleton()
{
Console.WriteLine("インスタンスを生成しました。");
}
public static Singleton GetInstance()
{
return _singleton;
}
}
}
ConfirmSingletonクラス
ConfirmSingletonクラスは、Singletonを利用しているクラスです。
ここでは、SingletonクラスのgetInstanceメソッドを使ってSingletonのインスタンスを得ています。
getInstanceメソッドは2回呼び出されています。戻り値はそれぞれobj1とobj2に代入しています。
確かに同じインスタンスが得られているかどうかを、obj1==obj2という式でチェックしています。
using System;
namespace SingletonSample
{
public class ConfirmSingleton
{
public static void Main(string[] args)
{
Console.WriteLine("Start");
Singleton obj1 = Singleton.GetInstance();
Singleton obj2 = Singleton.GetInstance();
if (obj1 == obj2)
{
Console.WriteLine("obj1とobj2は同じインスタンスです。");
}
else
{
Console.WriteLine("obj1とobj2は同じインスタンスではありません。");
}
Console.WriteLine("End");
Console.ReadLine();
}
}
}
実行結果
先のMainを実行した結果は以下の通りです。
Start.
インスタンスを生成しました。
obj1とobj2は同じインスタンスです。
End.
どんなクラスをSingletonにするケースがあるか
- キャッシュクラス
ファイルへのアクセス処理は非常に負荷がかかり、処理速度に影響を及ぼします。
ファイルの内容の更新は行われないが、参照は頻繁に行われるようなファイルを毎回読み込むのは、効率が良いとは言えません。
そんなとき、 キャッシュ機構をもつクラスをSingleton化することで、アプリケーションが終了しない限り、キャッシュに保持されたデータをあらゆる局面で取り出すことができるようにできます。
参考URL :
http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html
Singletonは使うべきはないという意見もある
本エントリーでは取り上げませんが、以下のサイトでSingletonパターンを使うべきではない理由がまとめられています。興味のある方はご覧になってみてください。
まとめ
- Singletonパターンはインスタンスが1つしか存在しないことを保証するデザインパターン
- インスタンスを得るためのstaticメソッドを用意する
- クラスの外からnewされないようにコンストラクタをprivateにする
サンプルコード
以下に公開しています。
https://github.com/Keenag/SampleCode