シングルトンとは何ですか、いつ使用する必要がありますか?
X
ば話ができY
ますか?Y
シングルトンを作成するだけです!)、テスト/デバッグと手続き型のプログラミングスタイルが困難になります。時にはシングルトンが必要です。ほとんどの場合、そうではありません。
シングルトンとは何ですか、いつ使用する必要がありますか?
X
ば話ができY
ますか?Y
シングルトンを作成するだけです!)、テスト/デバッグと手続き型のプログラミングスタイルが困難になります。時にはシングルトンが必要です。ほとんどの場合、そうではありません。
回答:
シングルトンは、それ自体のインスタンスを1つだけ作成することを許可するクラスであり、そのインスタンスへのシンプルで簡単なアクセスを提供します。シングルトンの前提は、ソフトウェア開発全体にわたるパターンです。
C#の実装" C#でのシングルトンパターンの実装"があり、スレッドの安全性に関するいくつかの優れたアドバイスなど、知っておく必要のあることのほとんどをカバーしています。
正直に言うと、シングルトンを実装する必要があることは非常にまれです-私の意見では、あまり頻繁に使用されていなくても、それはあなたが知っておくべきことの1つであるはずです。
Lazy<T> Class
です。
あなたはC#を求めました。簡単な例:
public class Singleton
{
private Singleton()
{
// Prevent outside instantiation
}
private static readonly Singleton _singleton = new Singleton();
public static Singleton GetSingleton()
{
return _singleton;
}
}
概要:アプリケーションの存続期間全体で1つの永続的なインスタンスのみが存在するクラス。シングルトンパターンを参照してください。
使用する場合:可能な限り少ない。あなたがそれが必要だと絶対に確信している場合にのみ。私は「絶対にしない」とは言いたがりませんが、通常は、依存性注入や単に静的クラスなど、より優れた代替手段があります。
c#でシングルトンを実装する別の方法として、メソッドではなくプロパティとしてシングルトンクラスのインスタンスにアクセスできるため、個人的にはこの方法を好みます。
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
//instance methods
}
しかし、まあ、私が知っている限り、両方の方法は「正しい」と考えられているので、それは個人的な趣味のものです。
using System;
using System.Collections.Generic;
class MainApp
{
static void Main()
{
LoadBalancer oldbalancer = null;
for (int i = 0; i < 15; i++)
{
LoadBalancer balancerNew = LoadBalancer.GetLoadBalancer();
if (oldbalancer == balancerNew && oldbalancer != null)
{
Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server);
}
oldbalancer = balancerNew;
}
Console.ReadKey();
}
}
class LoadBalancer
{
private static LoadBalancer _instance;
private List<string> _servers = new List<string>();
private Random _random = new Random();
private static object syncLock = new object();
private LoadBalancer()
{
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
私はdofactory.comからコードを取得しましたが、それほど凝ったものではありませんが、Jooth BishopがC#3.0で追加したFoo and Barの例のデザインパターンよりもはるかに優れていることがわかります。
コードを見ると、実際には新しいオブジェクトがforループで構築されているため、新しいオブジェクトが作成されますが、oldbalancerとnewbalancerが同じインスタンスを持つインスタンスが再利用されます。方法 これは、関数GetLoadBalancer()で静的キーワードが使用されているため、ランダムリストである別のサーバー値があるにもかかわらず、GetLoadBalancer()の静的は、特定のオブジェクトではなくタイプ自体に属しています。
さらに、ここにはダブルチェックロックがあります
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
MSDNから
lockキーワードは、別のスレッドがクリティカルセクションにある間、1つのスレッドがコードのクリティカルセクションに入らないようにします。別のスレッドがロックされたコードを入力しようとすると、オブジェクトが解放されるまで待機、ブロックされます。
そのため、必要がない場合でも、相互排除ロックが毎回発行されるため、nullチェックが行われます。
うまくいけば、それはより多くをクリアするのに役立ちます。
そして、私の理解が間違った方向を向いている場合はコメントしてください。
これは設計パターンであり、c#に固有のものではありません。このWikipediaの記事のように、インターネットとSO全体の詳細について。
ソフトウェアエンジニアリングでは、シングルトンパターンは、クラスのインスタンス化を1つのオブジェクトに制限するために使用される設計パターンです。これは、システム全体でアクションを調整するために1つのオブジェクトのみが必要な場合に役立ちます。この概念は、オブジェクトが1つだけ存在する場合、またはインスタンス化を特定の数のオブジェクト(たとえば、5つ)に制限する場合に、より効率的に動作するシステムに一般化されることがあります。一部は、それが過度に使用されていると判断してアンチパターンと見なし、クラスの唯一のインスタンスが実際には必要とされない状況で不要な制限を導入し、グローバル状態をアプリケーションに導入します。
一度だけインスタンス化できるクラスが必要な場合は、これを使用する必要があります。
ルックアップデータに使用します。DBから1回ロードします。
public sealed class APILookup
{
private static readonly APILookup _instance = new APILookup();
private Dictionary<string, int> _lookup;
private APILookup()
{
try
{
_lookup = Utility.GetLookup();
}
catch { }
}
static APILookup()
{
}
public static APILookup Instance
{
get
{
return _instance;
}
}
public Dictionary<string, int> GetLookup()
{
return _lookup;
}
}
シングルトンとは:
これは、それ自体の1つのインスタンスの作成のみを許可するクラスであり、通常、そのインスタンスへの単純なアクセスを提供します。
いつ使うべきか:
状況による。
注:db接続では使用しないでください。詳細な回答については、@ Chad Grantの回答を参照してください
の簡単な例を次に示しますSingleton
。
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
を使用してLazy<T>
を作成することもできますSingleton
。
シングルトンは次のとおりです。http://en.wikipedia.org/wiki/Singleton_pattern
C#は知りませんが、実際にはすべての言語で同じであり、実装のみが異なります。
可能な場合は通常、シングルトンを避ける必要がありますが、状況によっては非常に便利です。
私の英語でごめんね;)
シングルトンクラスは、アプリケーションドメイン全体の単一のインスタンスを作成するために使用されます。
public class Singleton
{
private static Singleton singletonInstance = CreateSingleton();
private Singleton()
{
}
private static Singleton CreateSingleton()
{
if (singletonInstance == null)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
public static Singleton Instance
{
get { return singletonInstance; }
}
}
で、この記事では説明している私たちは読み取り専用変数とアプリケーションでの実用化を使用してスレッドセーフなシングルトンクラスを作成する方法。
EX注入する必要があるグローバル情報にシングルトンを使用できます。
私の場合、ログに記録されたユーザーの詳細(ユーザー名、権限など)をグローバル静的クラスに保持していました。ユニットテストを実装しようとしたときに、コントローラークラスに依存関係を注入する方法がありませんでした。したがって、静的クラスをシングルトンパターンに変更しました。
public class SysManager
{
private static readonly SysManager_instance = new SysManager();
static SysManager() {}
private SysManager(){}
public static SysManager Instance
{
get {return _instance;}
}
}
http://csharpindepth.com/Articles/General/Singleton.aspx#cctor
特定のクラスのインスタンスを1つだけ作成し、そのインスタンスへの単純なグローバルアクセスをアプリケーション全体に提供する必要がある場合は、C#でシングルトンデザインパターンを使用する必要があります。
シングルトンデザインパターンを使用できるリアルタイムシナリオ:サービスプロキシ:ご存知のように、サービスAPIの呼び出しは、アプリケーションでの広範な操作です。ほとんどの時間を費やしているプロセスは、サービスAPIを呼び出すためにサービスクライアントを作成しています。サービスプロキシをシングルトンとして作成すると、アプリケーションのパフォーマンスが向上します。
ファサード:データベース接続をシングルトンとして作成して、アプリケーションのパフォーマンスを向上させることもできます。
ログ:アプリケーションでは、ファイルに対するI / O操作の実行は負荷の高い操作です。ロガーをシングルトンとして作成すると、I / O操作のパフォーマンスが向上します。
データ共有:定数値または構成値がある場合は、これらの値をシングルトンに保持して、アプリケーションの他のコンポーネントから読み取れるようにすることができます。
キャッシュ:ご存知のように、データベースからのデータのフェッチは時間のかかるプロセスです。アプリケーションでは、マスターと設定をメモリにキャッシュして、DB呼び出しを回避できます。このような状況では、Singletonクラスを使用して、スレッド同期によるキャッシュを効率的に処理し、アプリケーションのパフォーマンスを大幅に向上させることができます。
C#でのシングルトンデザインパターンの短所C#でのシングルトンデザインパターンの短所は次のとおりです。
ユニットテストは、アプリケーションにグローバルな状態を導入するため、非常に困難です。マルチスレッド環境でシングルトンインスタンスにアクセスするには、ロックを使用してオブジェクトをシリアル化する必要があるため、プログラム内での並列処理の可能性が低くなります。
これは次の記事から引用しています。
https://dotnettutorials.net/lesson/singleton-design-pattern/