In C # i metodi statici hanno a lungo servito uno scopo che ci consente di chiamarli senza creare classi di istanziazione. Solo nell'ultimo anno siamo diventati più consapevoli dei problemi legati all'utilizzo di metodi e classi statici.
- Non possono utilizzare le interfacce
- Non possono utilizzare l'ereditarietà
- Sono difficili da testare perché non puoi fare mock e stub
C'è un modo migliore? Ovviamente dobbiamo essere in grado di accedere ai metodi di libreria senza classi istanziate per tutto il tempo altrimenti il nostro codice diventerebbe piuttosto disordinato
Una possibile soluzione è usare una nuova parola chiave per un vecchio concetto: the singleton . Singleton sono istanze globali di una classe, dal momento che sono casi in cui possiamo usarle come faremmo con le normali classi. Per rendere il loro uso piacevole e pratico avremmo bisogno di un po 'di zucchero sintattico comunque
Supponete che la classe Math sia di tipo singleton invece di una classe effettiva. La classe effettiva contenente tutti i metodi predefiniti per il singleton Math è DefaultMath, che implementa l'interfaccia IMath. Il singleton verrebbe dichiarato come
singleton Math : IMath
{
public Math
{
this = new DefaultMath();
}
}
Se volessimo sostituire la nostra classe per tutte le operazioni matematiche, potremmo creare una nuova classe
MyMath che eredita DefaultMath , oppure potremmo ereditare dall'interfaccia IMath e creare una classe completamente nuova. Per rendere la nostra classe la classe Math attiva, dovresti fare un semplice incarico
Math = new MyMath();
e voilá! la prossima volta che chiameremo Math.Floor chiamerà il tuo metodo. Nota che per un normale singleton dovremmo scrivere qualcosa come Math.Instance.Floor ma il compilatore elimina la necessità della proprietà Instance
Un'altra idea sarebbe quella di essere in grado di definire un singleton come Lazy in modo che vengano istanziati solo quando vengono chiamati per la prima volta, come
lazy singleton Math : IMath
Cosa ne pensi, sarebbe stata una soluzione migliore per metodi e classi statici? C'è qualche problema con questo approccio?
Addendum
Alcuni punti sono stati sollevati, che uno dei principali vantaggi dei metodi statici è quello di avere metodi "stateless" e quindi di effetti collaterali liberi in una certa misura dal punto di vista della concorrenza. Sono pienamente d'accordo che questo è un punto valido. Tuttavia stiamo mescolando qui due problemi e problemi diversi: uno sta rendendo alcuni metodi invocabili e accessibili a livello globale senza dover creare un'istanza in modo esplicito. L'altro sta avendo metodi che sono apolidi.
Il secondo problema potrebbe essere risolto con un metodo che ha qualcosa come una parola chiave senza stato che in modo simile alla statica ha impedito loro di chiamare questo o forse fare ancora di più per applicare nessun effetto collaterale. Con singoletti piuttosto che classi statiche e qualcosa come classi e metodi apolidi penso che avresti i seguenti pro e contro
Pro
- Metodi "statici" in altre classi e le classi quadro potrebbero facilmente essere progettato per essere sovrascrivibile
- Le classi sarebbero più facili da testare
- Utilizzare le istanze anziché le classi statiche significa che i modelli di progettazione funzionano meglio (cose come le fabbriche)
- Nessuna limitazione di ereditarietà e polimorfismo in contrasto con statico
Contro
- Forse prestazioni leggermente peggiori?
- I programmatori cattivi faranno tutto in singleton per renderli accessibili a livello globale invece di usare dependency injection, forse dovresti essere in grado di accedere solo ai metodi singleton e non a proprietà / campi per evitare variabili globali:)
Forse Math era un cattivo esempio, ma immagina che se i metodi di stringa .Net fossero inefficienti, potresti facilmente sostituirli con il tuo usando questo metodo. Oppure alcune classi di terze parti hanno un metodo singleton che vuoi leggermente modificare, puoi ereditare e modificare quel metodo