概要:
シングルトン(Singleton)は、特定のクラスが単一のインスタンスのみを生成し、そのアクセスを制御する設計パターンです。グローバル変数を使用してオブジェクトにアクセスする方法もありますが、複数のインスタンス生成を防ぐには、クラス自身がインスタンスを管理する仕組みが必要です。このパターンは、インスタンス生成を完全に制御し、外部からのアクセスを一元管理するための効果的な手段です。
適用場面:
- クラスが1つのみのインスタンスでなければならない場合。
- クライアントが拡張可能なサブクラスを扱えるようにし、コード変更なしで拡張機能を利用できる場合。
クラス図:
コード例:
class UniqueInstance<br></br>{<br></br> private static UniqueInstance instance;<br></br> // コンストラクタをプライベートに設定し、外部からのインスタンス生成を防ぐ<br></br> private UniqueInstance()<br></br> {}<br></br><br></br> public static UniqueInstance GetUniqueInstance()<br></br> {<br></br> if(null == instance)<br></br> {<br></br> instance = new UniqueInstance();<br></br> }<br></br> return instance;<br></br> }<br></br>}
テストコード(フロントエンド)
static void Main(string[] args)<br></br>{<br></br> UniqueInstance u1 = UniqueInstance.GetUniqueInstance();<br></br> UniqueInstance u2 = UniqueInstance.GetUniqueInstance();<br></br> if(u1 == u2)<br></br> {<br></br> Console.Write("同一のインスタンス");<br></br> }<br></br> Console.Read();<br></br>}
スレッドセーフな実装:複数のスレッドが同時にGetInstance()を呼び出すと、インスタンスが複数生成される可能性がある。これを回避するには、lock文で排他制御を行うことで、1つのスレッドが処理中である間、他のスレッドの実行をブロックする。
class ThreadSafeSingleton<br></br> {<br></br> private static ThreadSafeSingleton instance;<br></br> // 静的ロック用オブジェクト<br></br> private static readonly object lockObject = new object();<br></br> private ThreadSafeSingleton() { }<br></br> /// <summary><br></br> /// ダブルチェックによるスレッドセーフ処理<br></br> /// </summary><br></br> /// <returns></returns><br></br> public static ThreadSafeSingleton GetInstance() <br></br> {<br></br> if (instance == null) <br></br> {<br></br> lock (lockObject)<br></br> {<br></br> if (instance == null)<br></br> {<br></br> instance = new ThreadSafeSingleton();<br></br> }<br></br> }<br></br> }<br></br><br></br> return instance;<br></br> }<br></br> }
C#では静的初期化によりスレッドセーフ性を確保できるが、クラス読み込み時にインスタンスが生成されるためリソースを事前に消費する。必要に応じてロック機構による遅延初期化を採用する方法も有効である。
/// <summary><br></br> /// 派生を禁止するsealed修飾子<br></br> /// </summary><br></br> public sealed class ConfigManager<br></br> {<br></br> // readonlyで静的初期化、最初の呼び出し時にCLRが初期化を処理<br></br> private static readonly ConfigManager config = new ConfigManager();<br></br><br></br> private ConfigManager() { }<br></br><br></br> public static ConfigManager GetInstance() <br></br> {<br></br> return config; <br></br> }<br></br><br></br> }
まとめ:
シングルトンパターンはデータベース接続管理や設定ファイル読み込みなどのユースケースで頻繁に利用されます。インスタンス生成の制御とリソース管理の観点から、実装方法の選択は状況に応じて柔軟に行う必要があります。