こんにちは、せのり(@senoriblog)です!
今回はデザインパターンの1つ、シングルトンパターン(Singleton)を紹介します。
本記事は、以下のような方を対象にしています。
- シングルトンパターン?何それって方
それでは行きしょう!!
シングルトンパターンとは?
クラスのインスタンスが1つしか生成されないことを保証(制限)するデザインパターンのこと。
例えば以下のソースコードの場合(独習C# 新版から参照)
1 2 3 4 5 6 7 8 9 10 11 12 |
class MySingleton [ private static MySingleton instance = new MySingleton(); private MySingleton(){} // あらかじめ用意しておいたインスタンスを取得 public static MySingleton Instance { get { return instance; } } } |
ポイントはコンストラクタを private にしていること。
そのため、クラスの利用者(クライアント)は以下のように MySingleton クラスをインスタンス化することができません。
MySingleton mySingleton = new MySingleton();
どのように利用するかと言うと、公開プロパティInstance
を使用します。
MySingleton mySingleton = MySingleton.Instance;
MySingleton は2行目でを既にインスタンス化されているので、Instance
経由でそのインスタンスを取得できます。
いつ使うの?
あるクラスのインスタンスを1つしか生成したくないときに使います。
例えばログクラス。
ログ出力する際、一時的にインスタンスに出力内容を保持すると思いますが、
複数のプログラムからインスタンス生成してログ出力すると、
出力内容をどこかでマージする必要が出てきます。
シングルトンでインスタンスの生成を制限しておけば、出力内容のマージは不要になります。
あとはクラス間でデータ共有したい場面ですね。
class A でシングルトンクラスのインスタンス生成⇒データ編集⇒class B で class A で編集したデータを使用とか。
クラスでインスタンスが1つしか生成できないので、初めに作成したインスタンスを別クラスと兼用することができます。
サンプルプログラム
例にあげたシングルトンのログクラスです。
コンストラクタは private、公開プロパティ(GetInstance)でインスタンスを返却しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Text; namespace MyUtility { /// <summary> /// ログ出力クラス /// </summary> /// ログ出力を行う。※インスタンス化不要。公開プロパティ[Instance]経由でアクセス public class Logger { #region "メンバー変数" // シングルトンクラスアクセス用変数 private static readonly Logger instance = new Logger(); #endregion #region "公開プロパティ" /// クラスインスタンスアクセス用 public static Logger GetInstance { get { return instance; } } #endregion #region "コンストラクタ" private Logger() { // 各プロパティに初期値を設定 // ログ出力先ディレクトリ LogFileDir = System.AppDomain.CurrentDomain.BaseDirectory + "\\log"; // ログファイル名 LogFileName = "TraceLog"; // ログファイルの書込モード LogWriteMode = LogWriteModeType.Append; // ログファイル名のフォーマット LogFormatFileName = LogFormatFileNameType.YYYYMMDD; // ログファイルの出力レベル LogOutPutLevel = LogLevel.Info; // エンコード Encode = "shift_jis"; } #endregion 中略・・・ |
ログクラスに関しては以下記事でまとめています!
-
【C#】自作ログクラスを作成しよう!【log4netなし】
まとめ
今回はシングルトンパターンについてまとめました。
シングルトンパターンの使い道やメリットが伝わりましたでしょうか?
ログ出力のように1アプリケーション上で明確に1つだけに制限したい場合に有用です。
ただし、多用するとプログラムの結合度が高くなり単体テストがしづらくなるデメリットもあります。
使用する際はしっかり見極めましょう。
今回は以上です。それでは!!