本文へスキップ
BecomeCoder

C#デザインパターンコース · 第1章 デザインパターン · レッスン4

生成④:Singleton

ブラウザで完結

導入

Singletonは「そのクラスのインスタンスは常に1つだけ」を保証するパターンです。設定・ログ・接続プールなど、アプリ全体で共有したい唯一の存在に使います。

図解

flowchart TB
    A["どこから呼んでも"] --> S["AppConfig.Instance"]
    B["別の場所から呼んでも"] --> S
    S --> ONE["常に同じ1つの実体"]
    style ONE fill:#e8f5e9

サンプル

// どこから取得しても同じ1つのインスタンス
AppConfig.Instance.AppName = "BecomeCoder";
Console.WriteLine(AppConfig.Instance.AppName);   // BecomeCoder

var a = AppConfig.Instance;
var b = AppConfig.Instance;
Console.WriteLine(ReferenceEquals(a, b));        // True(同一の実体)

class AppConfig
{
    // static readonly で唯一のインスタンスを保持
    public static AppConfig Instance { get; } = new AppConfig();

    private AppConfig() { }   // コンストラクタを private にして外部の new を禁止

    public string AppName { get; set; } = "";
}
  • コンストラクタをprivateにして外部からのnewを禁止する
  • staticInstanceで唯一のインスタンスを公開する
  • ただし乱用は「どこからでも触れるグローバル状態」になりテストを難しくする。実務ではDIコンテナSingleton登録する方式が主流

演習

Counter.Instance.Increment();
Counter.Instance.Increment();
Console.WriteLine(Counter.Instance.Value);   // 2

// TODO: インスタンスが常に1つの Counter を定義してください
//       (Instance プロパティ / private コンストラクタ / Increment() / Value)
___
  • 期待される出力: 2
ヒント1を見る

public static Counter Instance { get; } = new Counter(); private Counter() { }

ヒント2を見る

class Counter { public static Counter Instance { get; } = new Counter(); private Counter() { } public int Value { get; private set; } public void Increment() => Value++; }

まとめ

  • Singletonはインスタンスを常に1つに保証する
  • privateコンストラクタ+static Instanceで実現
  • 乱用はグローバル状態化するため、実務ではDI管理が主流

次回: 構造パターンへ。互換性をつなぐAdapterBridgeです。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。