広告あり

【C#】インスタンスは一つだけ!~シングルトン(singleton)パターン~

C#

C#でコーディングをしていると、特定のクラスで生成するインスタンスを1つだけにしたい場合がありますよね。たとえば、設定情報やログ機能などをアプリケーション全体で共有したいときなど。どのように実現すればよいのでしょうか?その答えが、デザインパターンの1つであるシングルトンパターンです。

この記事では、初心者でも分かりやすいようにシングルトンパターンについて解説します!具体的な実装例、メリットとデメリット、応用方法までカバーしているので、ぜひ最後までお読みください!

[スポンサーリンク]

シングルトン(Singleton)パターンとは?

シングルトン(Singleton)パターンは、クラスのインスタンスを1つだけ生成し、それをアプリケーション全体で共有するデザインパターンです。これにより、リソースの効率的な使用とデータの一貫性を保つことができます。

C#でのシングルトンパターン実装方法

C#での基本的なシングルトンパターンの実装例を示します。

実装例1:シンプルなシングルトン

public class Singleton
{
    private static Singleton instance;

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }

    // コンストラクタを private にして外部からのインスタンス生成を防ぐ
    private Singleton()
    {
        // TODO: initialize
    }

    public void ShowMessage()
    {
        Console.WriteLine("シングルトンインスタンスのメソッドが実行されました!");
    }
}

// 利用例
class Program
{
    static void Main(string[] args)
    {
        Singleton singleton = Singleton.Instance;
        singleton.ShowMessage();
    }
}

ポイント解説:

  1. コンストラクタをprivateにして外部からのインスタンス生成を禁止。(18行目)
  2. 静的プロパティInstanceを通じて唯一のインスタンスを管理。(5行目)
  3. インスタンスが未生成の場合、静的プロパティInstanceで生成。(11行目)

この基本的な実装では、静的プロパティInstanceを通じて1つのインスタンスを生成・管理します。しかし、この方法はマルチスレッドアプリケーションでは安全ではありません

実装例2:マルチスレッド環境におけるスレッドセーフなシングルトン

public class Singleton
{
    private static Singleton instance;
    private static readonly object lockObj = new object();

    public static Singleton Instance
    {
        get
        {
            lock (lockObj)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
            }
            return instance;
        }
    }

    private Singleton()
    {
        // TODO: initialize
    }
}

ポイント解説:

  1. メンバーにlockステートメント用のオブジェクトを追加。(4行目)
  2. lockステートメントによりlockスコープ内(lock以下の中かっこ{}内)は1つのスレッドが排他的にアクセスするように制限される。(10行目)

この方法では、lockステートメントを使用してスレッド間の競合を防いでいます。

実装例3:静的初期化を活用したスレッドセーフな実装(★おすすめ)

public class Singleton
{
    private static readonly Singleton instance = new Singleton();

    public static Singleton Instance => instance;

    private Singleton()
    {
        // TODO: initialize
    }
}

ポイント解説:

  1. 静的メンバーの初期化を追加。(3行目)
    ※静的メンバーは初めてアクセスされる際に初期化される
  2. getアクセサーでのインスタンス管理が不要になる。(5行目)

静的初期化を活用すると、C#ランタイムが自動的にスレッドセーフを保証してくれるので、コードが簡潔で効率的です。

シングルトンパターンのメリットとデメリット

メリット

  • リソース効率の向上:インスタンス生成を最小限に抑えられる。
  • 一貫性のあるデータ共有:同じインスタンスをアプリケーション全体で利用可能。
  • グローバルアクセス:1つのインスタンスに容易にアクセス可能。

デメリット

  • テストが難しい:シングルトンパターンはグローバルな状態を持つため、単体テスト(ユニットテスト)でモック(テスト用の模擬オブジェクト)が使いにくい。
  • 柔軟性の低下:乱用するとコードが密結合になり、拡張性が損なわれることがある。
  • 依存性の問題:依存性注入(DI)フレームワークとの組み合わせには工夫が必要。

シングルトンパターンの活用例

シングルトンパターンは、以下のような場面で役立ちます。

  • 設定情報の管理:アプリケーション全体で共有される設定情報(DB接続文字列、APIキーなど)を管理する際に便利です。
  • ログ機能の一元化:全てのクラスが同じログインスタンスを使用することで、時系列や出力先など一貫性のあるログ記録が可能になる。
  • データベース接続の効率化:データベース接続を1つのインスタンスだけで保持し、リソースの使用を最適化する。

まとめ

C#のシングルトンパターンは、効果的に活用することでアプリケーション開発をより効率的にします。本記事では、初心者でも理解しやすい基本実装やメリットとデメリット、さらに実際の活用例について解説しました。これを機に、シングルトンパターンを実際のプロジェクトで試してみてください!

[スポンサーリンク]

\ おすすめ書籍 /



この記事を書いた人
だんご丸

鉄鋼系SE歴 10年
金融系SE歴  6年
現在は音楽出版社のSE

●保有資格
初級システムアドミニストレータ
(現:ITパスポート)
基本情報技術者
応用情報技術者
情報セキュリティスペシャリスト
(現:情報処理安全確保支援士)
ネットワークスペシャリスト
情報セキュリティマネジメント
AWS認定クラウドプラクティショナー
AWS認定ソリューションアーキテクト - アソシエイト

だんご丸をフォローする
C#
[スポンサーリンク]
[スポンサーリンク]
だんご丸をフォローする
[スポンサーリンク]
タイトルとURLをコピーしました