Quando va bene usare una variabile globale


22

Ok, quindi questa è davvero una domanda da sostenitori del diavolo.

Quando vanno bene le variabili globali, e se mai, cosa useresti come alternativa?

Un interessante esempio di questa domanda: in che modo un campo di classe statica pubblica è diverso da un globale?


5
Codice completo , 2a edizione, §13.3.
Jerry Coffin,

1
Applicazioni multithreaded praticamente richiedono variabili globali.
Aqua


4
@aqua Le applicazioni multithread sono dove le variabili globali possono essere più dannose. Tutti odiano la complessa logica di blocco.
luiscubal,

1
@JerryCoffin Se pubblicare un link come risposta senza citare il passaggio pertinente è una cattiva pratica, lo è anche citare una sezione di un libro senza citare il passaggio pertinente. Soprattutto perché i libri non sono liberamente e facilmente ottenibili come le pagine Web.
Braden Best

Risposte:


18

Per quanto ne so, un campo statico pubblico è fondamentalmente un globale dato che può essere chiamato da qualsiasi luogo con l'eccezione che non ostruisce lo spazio dei nomi.

L'unica volta che uso personalmente variabili "globali" nel mio codice è sotto forma di campi statici pubblici immutabili. In questo caso non è necessario preoccuparsi del valore che viene rovinato da altre parti del programma e ovviamente è molto più bello che avere una dozzina di variabili con gli stessi valori permanenti in ogni classe.


2
Definirei un campo immutabile una costante .
Aioobe,

14

Personalmente, utilizzo i globi per la configurazione di runtime: se una proprietà di configurazione viene caricata all'avvio dell'applicazione e cambia solo di rado (e solo da un punto), è terribile e soggetto a errori passarlo a tutti i metodi che potrebbero essere necessari ad un certo punto. Meglio usare qualcosa che può essere messo in campo da qualsiasi luogo che abbia bisogno di usarlo, in quanto ciò non ingombra e oscura le firme del metodo e i siti di chiamata.


Utilizzeresti un globale puro per questo o un pubblico statico / Singleton?
ocodo,

1
@Slomojo: Sicuramente non un singleton. A seconda della situazione, statica su una classe di configurazione o globali semplici con un CONFIG_o CFG_prefisso.
Anon.

+1 l'unica modifica che suggerirei è quella di dire "... soggetto a errori per passarlo ad ogni altro metodo in ogni altra classe". Altrimenti può essere considerato in classe con qualunque cosa serva - singleton penso.
Michael Durrant,

8

Escludendo i sistemi in tempo reale / incorporati, dovresti usare i globali solo per valori costanti, davvero. Se ritieni di non poter risolvere il tuo problema senza di loro, probabilmente stai facendo qualcosa di sbagliato.

Inoltre, guarda nello schema Singleton , freddo fornisce una soluzione migliore per i globali in quelle situazioni in cui hai bisogno di qualcosa per avere un punto di accesso globale.


8
Probabilmente suggerirei di evitare Singletons.
ocodo,

Non sto suggerendo che i singoli siano fantastici, ma penso ancora che battano molto le variabili globali.
Assapora Ždralo il

I valori costanti devono essere accessibili solo nell'area / modulo che sono rilevanti. Una costante TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPè rilevante solo nel file / classe / sezione in cui appare "questo particolare ciclo".
Cthulhu,

1
I campi di un singleton sono variabili globali, quindi non vedo come ci sia differenza.
sleske,

1
@Cthulhu mi permetta di citare me stesso: "in quelle situazioni in cui hai bisogno di qualcosa per avere un punto di accesso globale".
Davor Ždralo,

6

Il problema con le variabili globali è che devi essere consapevole di loro ovunque nel tuo codice. Tuttavia, una volta che hai deciso che devi conoscere un particolare globale, c'è poco più da perdere nell'usarlo pesantemente. Pertanto, la mia opinione è che dovresti avere pochissime variabili globali, ma le poche che hai, dovresti ottenere il massimo chilometraggio.

Per un altro esempio di qualcosa che provo in questo modo, guarda l'uso dei mixin in Ruby.


Quali esempi di utilizzo suggeriresti per questi usi dei globali?
ocodo,

1
@Slomojo: un esempio di globali che non mi dispiace è l'uso di @ARGV e $ _ in Perl. Un esempio che mi viene in mente è l'uso dei globali per i parametri economici che passano alle subroutine.
btilly,

5

Si tratta di spazi dei nomi.

Immagina per un momento che tutti nel mondo avessero lo stesso cognome. Che casino.

(In India, i Sikh hanno lo stesso cognome: Singh - Dai un'occhiata)


6
In passato riguardava gli spazi dei nomi, ma ora riguarda la sicurezza dei thread.
dan04,

6
@ dan04 Si tratta di non avere un design orribile con un'azione spettrale a distanza.
Tom Hawtin - affronta il

2
@ Tom: Forse possiamo chiamarlo così, ironicamente, "Programmazione quantistica"
Christopher Mahan,

4

Versione breve: quando rende più facile ragionare sul programma. In genere i casi sono un tipo di stato globale o risorsa statica ampiamente utilizzata.

Versione lunga: Tom Hawtin ha detto "con un'azione spettrale a distanza" ... questo è esattamente il problema con i globi - devi sapere dove viene utilizzato e come, oppure puoi ottenere qualcosa di veramente strano e difficile da rintracciare bug. I locali non sono altro che una strategia per ridurre la portata di ciò che il programmatore deve capire per ragionare sul programma.

Un altro aspetto del problema con sapere dove vengono utilizzati è che puoi finire con duplicati globali - nel qual caso le cose possono diventare davvero strane man mano che la maggior parte dei programmi ottiene e imposta var1 mentre in un paio di posti viene usato var2 le stesse informazioni. Soprattutto quando più persone stanno lavorando sullo stesso codice. Gli IDE possono essere utili per trovare l'utilizzo riducendo il costo dei globuli, ma non fanno nulla per i duplicati.

Più globuli hai, più è difficile tenere traccia di ciò che sta accadendo con loro. Dovrebbero essere pochi e lontani tra.


Avere globalmente mutevoli in definitiva è una pessima idea. L'unica eccezione decente è quando si lavora con impronte hardware estremamente strette, come con la programmazione integrata. Per lo meno, i candidati a livello globale nella programmazione regolare dovrebbero essere suddivisi in membri statici di classi o moduli, tutto ciò che è mutabile dovrebbe anche essere considerato un caso speciale, doppiamente quando si lavora in un ambiente multi-thread. Utilizzo di lock / future / promesse o qualche altro metodo di thread / sicurezza delle transazioni. - Dato che nessun altro lo ha menzionato, vede il problema dei filosofi da pranzo.
ocodo,

1
Senza dubbio i thread possono rendere più difficile lavorare con i globuli mutabili, ma puoi ottenere lo stesso problema di base a causa di eventi. Concordo con il suggerimento di inserirli come membri statici e andrei oltre e direi che idealmente dovrebbero essere membri statici PRIVATI.
jmoreno,

3

I due gotcha con globuli e singoli sono testabilità e schierabilità.

Per i test, ho visto troppi imbraghi di test troppo complessi solo per affrontare le vite globali e singleton mal pianificate. Assicurati che tali oggetti abbiano regole di avvio e abbattimento chiare e semplici.

Per quanto riguarda la schierabilità, ci sono due casi da considerare. Innanzitutto, come vivrà il tuo oggetto globale? È in una libreria statica o dinamica? Se quell'oggetto globale viene riutilizzato per un plug-in, otterrai copie extra? In secondo luogo, cosa succede quando l'oggetto globale viene rilasciato in un'applicazione parallela? È sicuro per i thread?

Nel complesso, immagino che queste ragioni significhino che globuli e singoli sono usati solo eccezionalmente.


2

Lo sviluppo di sistemi embedded critici di solito comporta l'uso di variabili globali.

Le dimensioni dello stack sono minuscole, tutto è allocato staticamente ( malloc()è vietato), le variabili globali sono nascoste dall'esterno della libreria a cui appartengono.


0

In un'orribile base di codice VB6 che abusa dei globi come se non ci fosse un domani, sono colpevole di introdurne uno nuovo:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Penso che sia uno dei pochi casi d'uso validi per un oggetto globale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.