Dipende da come è necessario utilizzare GetRules.
Se è costoso e vuoi davvero accedere allo stesso insieme di regole ovunque nella tua applicazione, creo una classe Cache
che memorizza l'elenco di regole.
In questa istanza (e quasi tutti gli altri) un Singleton sarebbe un modello di formica. Invece avresti un'interfaccia ICache
con un metodo GetRules
e un riferimento ICache
a ogni oggetto che ne ha bisogno.
Sebbene si tratti di un lavoro maggiore rispetto a quello di un Singleton (in realtà è sorprendentemente difficile implementare correttamente il pattern Singleton), ti offre una separazione corretta delle preoccupazioni e ti consente di sostituire il meccanismo dietro l'interfaccia ICache
. per esempio. Nel tempo trovi che è necessario aggiornare la cache ogni 8 ore. L'oggetto Cache può farlo, ma il codice client non deve essere modificato.
O trovi che devi implementare due diversi tipi di memorizzazione nella cache per due diversi giochi / client? Basta iniettare una diversa implementazione della cache.
Tra un anno, una parte dell'app in esecuzione ha bisogno di vedere le regole in tempo reale in un database e non può funzionare dalla cache? Inietti una cache diversa che non è effettivamente una cache ma restituisce regole live ogni volta che viene chiamata. Saresti nei guai con un singleton su quello.
Questo è un modo in cui puoi farlo. Avere una cache che restituisce regole, o un IRulesProvider
che sa come ottenere le regole.
Estrarre le regole, iniettare quell'astrazione nelle classi che necessitano di regole, quindi implementare quell'interfaccia.
Puoi ancora scegliere di creare solo un'istanza della classe che implementa IRulesProvider
, ma dipende da te, non hai bisogno di tutta la merda che arriva con il pattern Singleton, metà del quale è lì per proteggerti dalla creazione di più che su istanza della classe.
A questo punto potresti aver indovinato che in passato mi sono imbattuto in teste con Singletons. . . ha lasciato alcune cicatrici:)
Anche se non è costoso creare gli oggetti
Considera ancora il modello Provider. Ti dà una grande flessibilità e una corretta separazione delle preoccupazioni. Le cose che usano le regole possono ottenere regole, ma non sanno nemmeno quali regole possano ottenere. È uno schema davvero potente da seguire e lascia te e il tuo codice estremamente agili.
Un esempio di cosa intendo per modello di provider.
interface IRulesProvider
{
IEnumerable<IRule> GetRules();
}
class RulesProvider: IRulesProvider
{
IEnumerable<IRule> GetRules()
{
// return some rules;
}
}
Le regole sono memorizzate nella cache sull'oggetto RulesProvider
? vengono recuperati da un file Xml e memorizzati nella cache, vengono letti in tempo reale da un database ogni volta che viene chiamato GetRules
? È a te che quel corso ti inietta un IRulesProvider
in nessuno dei due sa né importa come il fornitore apprenda le regole (a meno che, naturalmente, non debba sapere , a quel punto abbiamo bisogno di un meccanismo diverso) .