Che cos'è un Singleton e quando dovrei usarlo?
X
parlare Y
? Basta fare Y
un singleton!), Che a sua volta porta a difficoltà di test / debugging e uno stile procedurale di programmazione. A volte sono necessari i Singleton; il più delle volte no.
Che cos'è un Singleton e quando dovrei usarlo?
X
parlare Y
? Basta fare Y
un singleton!), Che a sua volta porta a difficoltà di test / debugging e uno stile procedurale di programmazione. A volte sono necessari i Singleton; il più delle volte no.
Risposte:
Un singleton è una classe che consente di creare solo un'istanza di se stessa e fornisce un accesso semplice e facile a tale istanza. La premessa singleton è un modello per lo sviluppo del software.
Esiste un'implementazione in C # "Implementare il modello Singleton in C #" che copre la maggior parte di ciò che devi sapere, compresi alcuni buoni consigli sulla sicurezza del thread .
Ad essere onesti, è molto raro che tu debba implementare un singleton - secondo me dovrebbe essere una di quelle cose di cui dovresti essere a conoscenza, anche se non viene usato troppo spesso.
Lazy<T> Class
.
Hai chiesto C #. Esempio di prova:
public class Singleton
{
private Singleton()
{
// Prevent outside instantiation
}
private static readonly Singleton _singleton = new Singleton();
public static Singleton GetSingleton()
{
return _singleton;
}
}
Che cos'è: una classe per la quale esiste solo un'istanza persistente per tutta la durata di un'applicazione. Vedi Singleton Pattern .
Quando dovresti usarlo: il meno possibile. Solo quando sei assolutamente certo di averne bisogno. Sono riluttante a dire "mai", ma di solito esiste un'alternativa migliore, come l'iniezione di dipendenza o semplicemente una classe statica.
un altro modo per implementare singleton in c #, preferisco personalmente questo modo perché puoi accedere all'istanza della classe singeton come proprietà anziché come metodo.
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
//instance methods
}
ma bene, per quanto ne so entrambi i modi sono considerati "giusti", quindi è solo una questione di sapore personale.
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();
}
}
}
Ho preso il codice da dofactory.com , niente di così fantasioso, ma lo trovo di gran lunga migliore degli esempi con Foo and Bar, inoltre il libro di Judith Bishop su C # 3.0 Design Patterns ha un esempio sull'applicazione attiva in Mac Dock.
Se osservi il codice, in realtà stiamo costruendo nuovi oggetti per il ciclo, in modo da creare un nuovo oggetto ma riutilizzare l'istanza a seguito della quale oldbalancer e newbalancer hanno la stessa istanza, come? è dovuto alla parola chiave statica utilizzata sulla funzione GetLoadBalancer () , nonostante abbia un valore del server diverso che è un elenco casuale, statico su GetLoadBalancer () appartiene al tipo stesso piuttosto che a un oggetto specifico.
Inoltre c'è un doppio controllo di blocco qui
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
da allora da MSDN
La parola chiave lock assicura che un thread non entri in una sezione critica del codice mentre un altro thread si trova nella sezione critica. Se un altro thread tenta di inserire un codice bloccato, attenderà, bloccherà, fino al rilascio dell'oggetto.
quindi ogni volta che viene emesso un blocco di esclusione reciproca, anche se non è necessario, il che non è necessario, quindi abbiamo un controllo nullo.
Speriamo che aiuti a chiarire di più.
E per favore commenta se la mia comprensione sta indirizzando modi sbagliati.
Un Singleton (e questo non è legato a C #, è un modello di progettazione OO) è quando si desidera consentire a UNA sola istanza di una classe di essere creata in tutta l'applicazione. Gli utilizzi in genere includono risorse globali, sebbene, per esperienza personale, dirò che spesso sono fonte di grande dolore.
È un modello di progettazione e non è specifico per c #. Maggiori informazioni su Internet e SO, come in questo articolo di Wikipedia .
Nell'ingegneria del software, il modello singleton è un modello di progettazione utilizzato per limitare l'istanza di una classe a un oggetto. Ciò è utile quando è necessario esattamente un oggetto per coordinare le azioni nel sistema. Il concetto è talvolta generalizzato a sistemi che funzionano in modo più efficiente quando esiste un solo oggetto o che limitano l'istanza a un certo numero di oggetti (diciamo cinque). Alcuni lo considerano un anti-modello, ritenendo che sia abusato, introducono limitazioni non necessarie in situazioni in cui non è richiesta una sola istanza di una classe e introducono lo stato globale in un'applicazione.
Dovresti usarlo se vuoi una classe che può essere istanziata una sola volta.
Lo uso per i dati di ricerca. Carica una volta dal DB.
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;
}
}
Che cos'è un singleton:
è una classe che consente di creare solo un'istanza di se stessa e in genere consente un accesso semplice a tale istanza.
Quando usare:
dipende dalla situazione.
Nota: non utilizzare sulla connessione db, per una risposta dettagliata fare riferimento alla risposta di @Chad Grant
Ecco un semplice esempio di a 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;
}
}
}
Puoi anche usare Lazy<T>
per creare il tuo Singleton
.
Vedi qui per un esempio più dettagliato usandoLazy<T>
Ecco cos'è singleton: http://en.wikipedia.org/wiki/Singleton_pattern
Non conosco C #, ma in realtà è la stessa cosa in tutte le lingue, solo l'implementazione differisce.
Dovresti generalmente evitare singleton quando è possibile, ma in alcune situazioni è molto conveniente.
Mi scusi per il mio inglese ;)
La classe Singleton viene utilizzata per creare una singola istanza per l'intero dominio dell'applicazione.
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; }
}
}
In questo articolo viene descritto come possiamo creare una classe singleton thread-safe usando la variabile readonly e il loro uso pratico nelle applicazioni.
EX È possibile utilizzare Singleton per le informazioni globali che devono essere iniettate.
Nel mio caso, stavo mantenendo i dettagli dell'utente registrato (nome utente, autorizzazioni, ecc.) Nella classe statica globale. E quando ho provato a implementare il Test unit, non c'era modo di iniettare dipendenza nelle classi Controller. Così ho cambiato la mia classe statica in modello Singleton.
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
Dobbiamo usare il Singleton Design Pattern in C # quando dobbiamo assicurarci che verrà creata solo un'istanza di una particolare classe e quindi fornire un semplice accesso globale a quell'istanza per l'intera applicazione.
Scenari in tempo reale in cui è possibile utilizzare il modello di progettazione Singleton: proxy di servizio: come sappiamo invocare un'API di servizio è un'operazione estesa in un'applicazione. Il processo che impiega la maggior parte del tempo sta creando il client di servizio al fine di invocare l'API di servizio. Se si crea il proxy di servizio come Singleton, le prestazioni dell'applicazione miglioreranno.
Facciate: è anche possibile creare le connessioni al database come Singleton che possono migliorare le prestazioni dell'applicazione.
Registri: in un'applicazione, eseguire l'operazione I / O su un file è un'operazione costosa. Se si crea il Logger come Singleton, le prestazioni dell'operazione di I / O miglioreranno.
Condivisione dei dati: se si hanno valori costanti o valori di configurazione, è possibile conservare questi valori in Singleton in modo che possano essere letti da altri componenti dell'applicazione.
Memorizzazione nella cache: come sappiamo recuperare i dati da un database è un processo che richiede tempo. Nella tua applicazione, puoi memorizzare nella cache il master e la configurazione che eviteranno le chiamate DB. In tali situazioni, la classe Singleton può essere utilizzata per gestire la memorizzazione nella cache con la sincronizzazione dei thread in modo efficiente che migliora drasticamente le prestazioni dell'applicazione.
Svantaggi del Singleton Design Pattern in C # Gli svantaggi dell'utilizzo del Singleton Design Pattern in C # sono i seguenti:
Il test unitario è molto difficile perché introduce uno stato globale in un'applicazione. Riduce il potenziale di parallelismo all'interno di un programma perché per accedere all'istanza singleton in un ambiente multi-thread, è necessario serializzare l'oggetto utilizzando il blocco.
Ho preso questo dal seguente articolo.
https://dotnettutorials.net/lesson/singleton-design-pattern/
Thread Safe Singleton senza usare blocchi e nessuna istanza pigra.
Questa implementazione ha un costruttore statico, quindi viene eseguita una sola volta per Dominio Applicazione.
public sealed class Singleton
{
static Singleton(){}
private Singleton(){}
public static Singleton Instance { get; } = new Singleton();
}