C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#でシングルトンパターンを実装する方法を徹底解説!基本の考え方とサンプルコード


シングルトンパターンとは

シングルトンパターンは、GoFデザインパターンの中でも「生成(Creational)」に分類されるパターンのひとつです。

このパターンは、特定のクラスのインスタンスがアプリケーション内で必ず1つだけ生成されることを保証したい場合に使用します。生成された唯一のインスタンスが、アプリケーション全体の処理や状態の調整役を担います。

設定情報の管理、ログ出力、データベース接続など、複数のインスタンスが存在すると不整合が発生する可能性がある場面でよく活用されます。

実装のポイント

シングルトンパターンを正しく実装するには、以下のポイントを押さえておく必要があります。

  • すべてのコンストラクタを private にする:外部から自由にインスタンス化できないようにし、クラス内部でしか生成できない構造にします。
  • 静的プロパティで唯一のインスタンスを提供する:static プロパティ経由でのみアクセスできるようにし、インスタンスへのアクセスを一元管理します。
  • null 条件による遅延生成:インスタンスがまだ存在しない場合のみ新規生成することで、確実に1つのインスタンスだけが作られるようにします。

コード例

それでは、C#でシングルトンパターンを実装した具体例を見てみましょう。サンプルコードのポイントは次のとおりです。

  • sealed キーワードにより継承を禁止し、派生クラスから追加のインスタンスが生成されることを防ぎます。
  • null で初期化された private static フィールドが、唯一のインスタンスを保持します。
  • GetInstance プロパティ内の null 判定により、オブジェクトが1度しか生成されないことを保証します。
  • private コンストラクタにより、クラス自身の内部以外からのインスタンス化を防ぎます。
  • PrintDetails のような public メソッドは、シングルトンインスタンスを通じて呼び出せます。
public sealed class Singleton {
    private static int counter = 0;
    private static Singleton instance = null;
    public static Singleton GetInstance {
        get {
            if (instance == null)
            instance = new Singleton();
            return instance;
        }
    }
    private Singleton() {
        counter++;
        Console.WriteLine("Counter Value " + counter.ToString());
    }
    public void PrintDetails(string message) {
        Console.WriteLine(message);
    }
}
class Program {
    static void Main() {
        Singleton fromFacebook = Singleton.GetInstance;
        fromFacebook.PrintDetails("From Facebook");
        Singleton fromTwitter = Singleton.GetInstance;
        fromTwitter.PrintDetails("From Twitter");
        Console.ReadLine();
    }
}

実行結果

Counter Value 1
From Facebook
From Twitter

コンストラクタ内のカウンターが「1」と表示されていることから、Main メソッド内で GetInstance を2回呼び出してもインスタンスが1度しか生成されていないことが分かります。「fromFacebook」と「fromTwitter」の2つの変数は、どちらも同じインスタンスを参照しているのです。

補足:マルチスレッド環境での注意点

上記のシンプルな実装は、マルチスレッド環境下では安全とは言えません。複数のスレッドが同時に GetInstance にアクセスすると、異なるインスタンスが生成される可能性があります。実際の開発では、lock による排他制御や、.NET 4 以降で利用可能な Lazy<T> 型を使って、スレッドセーフなシングルトンを実装することが推奨されます。

  1. C++で学ぶコンポジットパターン(複合デザインパターン)の基礎と実装例

    コンポジットパターン(Composite Pattern)は、複数のオブジェクトからなるグループを、あたかも単一のオブジェクトであるかのように扱いたい場面で活用されるデザインパターンです。 このパターンでは、オブジェクトを木構造(ツリー構造)として組み立てることで、「部分」と「全体」の両方の階層を一貫した形で表現できます。オブジェクト群のツリー構造を生成するパターンであるため、GoFデザインパターンの分類では「構造に関するパターン(Structural Patterns)」に属します。 コンポジットパターンの基本概念 コンポジットパターンでは、自分自身と同じ型のオブジェクト群を内部に保持するク

  2. Pythonでパターンを出力する方法|三角形・数字・アルファベット・ピラミッドのコード例

    Pythonでパターンを出力するには、ネストされた(入れ子構造の)forループを使用します。外側のループで行数を制御し、内側のループで列数を処理します。そしてprint文を工夫することで、目的に応じたさまざまなパターンを作成できます。パターンには、星(アスタリスク)パターン、数字パターン、アルファベットパターンなどがあり、三角形やピラミッドなど、さまざまな形状にも対応できます。パターン出力の基本これらのパターンは、print文を少し変更しながらforループを組み合わせることで出力できます。基本的な考え方はどのパターンも共通しており、違いはごくわずかです。ここからは、代表的なパターンのコードを実