Le classi e i metodi statici globali sono nocivi?

È generalmente accettato che basarsi su cose globali è da evitare. Non usare le classi e i metodi statici essere la stessa cosa?

I dati globali sono cattivi. Tuttavia molti problemi possono essere evitati lavorando con metodi statici.

Prenderò la posizione di Rich Hickey su questo e lo spiegherò in questo modo:

Per build i sistemi più affidabili in C # usa metodi e classi statici, ma non dati globali. Ad esempio, se si consegna un object dati in un metodo statico e il metodo statico non accede a dati statici, si può essere certi che, dati i dati di input, l’output della funzione sarà sempre lo stesso. Questa è la posizione assunta da Erlang, Lisp, Clojure e ogni altro linguaggio di programmazione funzionale .

L’uso di metodi statici può semplificare notevolmente la codifica a più thread, poiché, se programmato correttamente, solo un thread avrà accesso a un dato insieme di dati alla volta. E questo è davvero ciò che si riduce a. Avere dati globali è negativo poiché è uno stato che può essere modificato da chi sa quale thread e in qualsiasi momento. I metodi statici consentono comunque un codice molto pulito che può essere testato con incrementi più piccoli.

So che questo argomento sarà object di accesi dibattiti, in quanto sfidare il processo di pensiero OOP di C #, ma ho scoperto che i metodi più statici che uso, più pulito e affidabile è il mio codice.

Questo video lo spiega meglio di me, ma mostra come i dati immutabili e i metodi statici possono produrre codice estremamente thread-safe.


Permettetemi di chiarire un po ‘di più alcuni problemi con i dati globali. I dati globali costanti (o di sola lettura) non sono tanto importanti quanto i dati globali mutabili (lettura / scrittura). Quindi se ha senso avere una cache globale di dati, usa i dati globali! In una certa misura ogni applicazione che utilizza un database avrà quella, dal momento che potremmo dire che tutto il database SQL è una enorme variabile globale che contiene i dati.

Quindi fare una dichiarazione generale come quella che ho fatto sopra è probabilmente un po ‘forte. Invece, diciamo che avere dati globali introduce molti problemi che possono essere evitati avendo invece i dati locali.

Alcune lingue come Erlang risolvono questo problema avendo la cache in un thread separato che gestisce tutte le richieste per quei dati. In questo modo sai che tutte le richieste e le modifiche a quei dati saranno atomiche e la cache globale non verrà lasciata in uno stato sconosciuto.

static non significa necessariamente globale. Le classi e i membri possono essere static private , quindi si applicano solo alla class specifica. Detto questo, avere troppi membri public static invece di usare i modi appropriati per passare i dati (chiamate di metodo, callback, ecc.) È in genere un cattivo progetto.

Se stai cercando di essere purista riguardo allo sviluppo di OO, la statica probabilmente non si adatta allo stampo.

Tuttavia, il mondo reale è più confuso della teoria e la statica è spesso un modo molto utile per risolvere alcuni problemi di sviluppo. Usali quando necessario e con moderazione.

Le variabili statiche mutabili sono cattive perché sono solo uno stato globale. La migliore discussione che conosco su questo è qui, sotto la voce “Perché le variabili globali dovrebbero essere evitate quando non necessarie” .

I metodi statici presentano diversi inconvenienti che spesso li rendono indesiderabili: il più importante è che non possono essere utilizzati polimorficamente.

In aggiunta a qualsiasi altra cosa detta, final static variabili final static vanno bene; le costanti sono una buona cosa. L’unica eccezione è quando / se dovresti semplicemente spostarli in un file di proprietà, per essere più facile da cambiare.

Primo, perché le vecchie variabili globali sono così cattive? Perché è lo stato accessibile da qualsiasi luogo, in qualsiasi momento. Difficile da tracciare.

Non ci sono problemi con i metodi statici .

Ciò lascia campi statici (variabili). Se dichiari un campo statico pubblico in una class, quella sarebbe veramente una variabile globale e sarebbe male.

Ma rendi privato il campo statico e la maggior parte dei problemi viene risolta. O meglio, sono limitati alla class contenente e ciò li rende risolvibili.

 public class Foo { private static int counter = 0; public static int getCounterValue() { return counter; } //... public Foo() { //other tasks counter++; } } 

Nel codice sopra puoi vedere che contiamo quanti oggetti Foo sono stati creati. Questo può essere utile in molti casi.

La parola chiave static non è globale, ti dice che è a livello di class, che può essere molto utile in vari casi. Quindi, in conclusione, le cose a livello di class sono statiche, le cose a livello di object non sono statiche.

I metodi statici vengono utilizzati per implementare i tratti in Scala. In C #, i metodi di estensione (che sono statici) soddisfano in parte quel ruolo. Ciò potrebbe essere visto, come affermano i sostenitori della DCI, come una “forma di ordine superiore del polimorfismo” .

Inoltre, è ansible utilizzare metodi statici per implementare le funzioni. Questo è ciò che F # usa per implementare i moduli . (E anche VB.NET .) Le funzioni sono utili per (non sorprendentemente) la programmazione funzionale. E a volte sono solo il modo in cui qualcosa dovrebbe essere modellato (come le “funzioni” nella class Math ). Ancora una volta, C # si avvicina qui.

Penso che la cosa negativa delle variabili globali sia l’idea di avere uno stato globale – variabili che possono essere manipolate ovunque e tendono a causare effetti collaterali indesiderati in aree remote di un programma.

I dati statici sarebbero simili alle variabili globali in quanto introducono una sorta di stato globale. I metodi statici non sono poi così male, supponendo che siano apolidi.

Non del tutto. Statico determina effettivamente quando, dove e quanto spesso viene istanziato qualcosa, non chi ha accesso ad esso.