デザインパターンはオブジェクト指向言語で使われる設計パターンのことです。
この記事ではそんなデザインパターンの1つである「シングルトンパターン」について紹介をしています。
シングルトンパターンについて知りたい方は、ぜひ参考にしてみてください。

オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
シングルトンパターンとは

「シングルトンパターン」(singleton)はあるクラスのインスタンスの数を1つだけに制限するデザインパターンです。
Singleton パターンとは、そのクラスのインスタンスが1つしか生成されないことを保証するデザインパターンのことである。ロケールやルック・アンド・フィールなど、絶対にアプリケーション全体で統一しなければならない仕組みの実装に使用される。「引用元:Wikipedia」
インスタンス化されたオブジェクトはアプリケーション全体で共有するので、シングルトンパターンはアプリケーションのグローバルな状態を管理するのに適しています。

シングルトンパターンの書き方
シングルトンパターンは、デザインパターンの中でもシンプルで概念が理解しやすいです。
以下に記載している書き方で記述すれば、クラスのインスタンスが1つしか生成されないことが保証されます。
シングルトンの書き方
- コンストラクタのアクセス修飾子をprivateにする。外部からnewできない。
- 生成したインスタンスは、アクセス修飾子がprivateのstatic変数に保存する。
- インスタンスの取得はstaticメソッドもしくはstaticプロパティから行えるようにする。
シングルトンパターンの注意点
注意すべき点として、シングルトンパターンを多用しすぎるとクラス間の結合度が高くなってしまい単体テストがしづらくなります。
シングルトンパターンはメモリを節約出来るという利点がありますが、何でもかんでもシングルトンパターンにするのは好ましくありません。
本当にインスタンスを1つだけに制限すべきかを考えた上で使用するようにしましょう。インスタンスが複数あっても別に困らなければシングルトンパターンを利用する必要はありません。
シングルトンパターンの使い道としてはグローバル管理しないといけないオブジェクトがある場合など限定されるでしょう。
シングルトンのサンプル

それでは早速サンプルコードをみてましょう。
Visual Studio のプロジェクトに新しいクラスを追加します。クラス名は任意の名称で構いません。ここでは「SingletonSample」としました。
namespace SingletonSample
{
class CSingleton
{
// コンストラクタのアクセス修飾子をprivateにする
private CSingleton()
{
// 初期化処理
}
// アクセス修飾子がprivateのstatic変数に生成したインスタンスを保存する
private static CSingleton singleInstance = null;
// インスタンスの取得はstaticプロパティもしくはstaticメソッドから行えるようにする
// staticメソッドの場合
public static CSingleton GetInstance()
{
if (singleInstance == null)
{
singleInstance = new CSingleton();
}
return singleInstance;
}
// staticプロパティの場合
//public static CSingleton Instance
//{
// get
// {
// if (singleInstance == null)
// {
// singleInstance = new CSingleton();
// }
// return singleInstance;
// }
//}
}
}
上記のクラスはコンストラクタがprivate
で定義されていますので、他のクラスがSingletonSample()
のようにしてインスタンスを生成する事ができません。
このクラスのインスタンスを生成したい場合は、GetInstance()
を利用します。初めてこのメソッドが呼び出された時にインスタンスを生成し、2回目以降に呼び出された時は最初に生成したインスタンスを返すようになっています。
これでクラスのインスタンスが1つしか生成されないことが保証されます。
念のため、サンプルコードのインスタンスの数が1つだけであることを確認してみます。
using System;
namespace ConsoleSample
{
class Program
{
static void Main()
{
var cs1 = CSingleton.Instance;
var cs2 = CSingleton.Instance;
var cs3 = CSingleton.Instance;
if (cs1 == cs2 && cs2 == cs3)
{
Console.WriteLine("インスタンスは同じです");
}
else
{
Console.WriteLine("インスタンスは違います");
}
}
}
}
実行結果
インスタンスは同じです
インスタンスを比較した結果、同じインスタンスであることが分かりました。
まとめ

シングルトンのクラスを実装する方法とシングルトンのクラスを設計する際の注意点を紹介しました。
シングルトンを乱用しすぎないように注意して、デメリットを理解した上で使用するようにしましょう。



以上、最後まで読んで頂きありがとうございました。