Quand est-il possible d'utiliser une variable globale

22

Ok, donc c'est vraiment une question d'avocat du diable.

Quand les variables globales sont-elles correctes, et si jamais, qu'utiliseriez-vous comme alternative?

Un cas parallèle intéressant à cette question, en quoi un champ de classe statique public est-il différent d'un champ global?

ocodo
la source
5
Code complet , 2e édition, §13.3.
Jerry Coffin
1
Les applications multithread nécessitent à peu près des variables globales.
aqua
4
@aqua Les applications multithread sont celles où les variables globales peuvent être les plus dommageables. Tout le monde déteste la logique de verrouillage complexe.
luiscubal
1
@JerryCoffin Si publier un lien comme réponse sans citer le passage pertinent est une mauvaise pratique, il en va de même pour citer une section d'un livre sans citer le passage pertinent. D'autant plus que les livres ne peuvent pas être obtenus librement et facilement comme les pages Web.
Braden Best

Réponses:

18

Pour autant que je sache, un champ statique public est essentiellement un champ global étant donné qu'il peut être appelé de n'importe où à l'exception qu'il n'obstrue pas l'espace de noms.

La seule fois où j'utilise personnellement des variables «globales» dans mon code, ce sont des champs statiques publics immuables. Dans ce cas, il n'est pas nécessaire de s'inquiéter de la valeur vissée par d'autres parties du programme et bien sûr, c'est beaucoup plus agréable que d'avoir une douzaine de variables avec les mêmes valeurs permanentes dans chaque classe.


la source
2
J'appellerais un champ immuable une constante .
aioobe
14

Personnellement, j'utilise des globaux pour la configuration d'exécution - si une propriété de configuration est chargée au démarrage de l'application et ne change que rarement (et seulement à partir d'un seul endroit), il est terrible et sujet aux erreurs de la transmettre à toutes les méthodes qui pourraient avoir besoin d'utiliser à un moment donné. Mieux vaut utiliser quelque chose qui peut être mis à portée de n'importe où qui a besoin de l'utiliser, car cela n'encombre pas et n'obscurcit pas vos signatures de méthode et vos sites d'appels.

Anon.
la source
Pourriez-vous utiliser un global pur pour cela ou un statique / Singleton public?
ocodo
1
@Slomojo: Certainement pas un singleton. Selon la situation, soit des statiques sur une classe de configuration, soit des globales simples avec un CONFIG_ou un CFG_préfixe.
Anon.
+1 le seul changement que je suggérerais serait de dire "... sujet à erreur pour le transmettre à toutes les autres méthodes de toutes les autres classes". Sinon, il peut être étudié en classe avec tout ce qui sert - singleton je pense.
Michael Durrant
8

Excluant les systèmes temps réel / embarqués, vous ne devriez vraiment utiliser des globaux que pour des valeurs constantes. Si vous sentez que vous ne pouvez pas résoudre votre problème sans eux, vous faites probablement quelque chose de mal.

En outre, examinez le modèle Singleton , il fournit à froid une meilleure solution pour les globaux dans les situations où vous avez besoin de quelque chose pour avoir un point d'accès global.

Davor Ždralo
la source
8
Je suggère probablement d'éviter les singletons.
ocodo
Je ne dis pas que les singletons sont excellents, mais je pense toujours qu'ils battent beaucoup les variables globales.
Davor Ždralo
Les valeurs constantes doivent uniquement être accessibles dans la zone / le module auquel elles sont pertinentes. Une constante TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPn'est pertinente que dans le seul fichier / classe / section où «cette boucle particulière» apparaît.
Cthulhu
1
Les champs d'un singleton sont des variables globales, donc je ne vois pas de différence.
sleske
1
@Cthulhu permettez-moi de me citer: "dans ces situations où vous avez besoin de quelque chose pour avoir un point d'accès global".
Davor Ždralo
6

Le problème avec les variables globales est que vous devez en être conscient partout dans votre code. Cependant, une fois que vous avez décidé que vous devez connaître un environnement particulier, il n'y a plus grand-chose à perdre à l'utiliser de manière intensive. Par conséquent, mon avis est que vous devriez avoir très peu de variables globales, mais le peu que vous avez, vous devriez obtenir un kilométrage maximum.

Pour un autre exemple de quelque chose que je ressens de la sorte, regardez l'utilisation des mixins dans Ruby.

btilly
la source
Quel exemple de cas d'utilisation suggéreriez-vous pour ces utilisations des globaux?
ocodo
1
@Slomojo: Un exemple de globaux ne me dérange pas est l'utilisation de @ARGV et $ _ en Perl. Un exemple qui me dérange est l'utilisation de globaux pour le passage de paramètres bon marché aux sous-programmes.
btilly
5

Tout tourne autour des espaces de noms.

Imaginez un instant que tout le monde dans le monde ait le même nom de famille. Quel bordel.

(En Inde, les Sikhs ont tous le même nom de famille: Singh - Jetez un œil)

Christopher Mahan
la source
6
Il sert à être tous sur les espaces de noms, mais maintenant il est sur la sécurité fil.
dan04
6
@ dan04 Il s'agit de ne pas avoir un design hideux avec une action effrayante à distance.
Tom Hawtin - tackline
2
@Tom: Peut-être que nous pouvons appeler cela, ironique, "Programmation Quantique"
Christopher Mahan
4

Version courte: quand elle facilite la réflexion sur le programme. Les cas sont généralement un type d'état global ou de ressource statique largement utilisé.

Version longue: Tom Hawtin a dit "avec une action effrayante à distance" ... c'est exactement le problème avec les globaux - vous devez savoir où il est utilisé et comment, ou vous pouvez en trouver des vraiment étranges et difficiles à retrouver bogues. Les sections locales ne sont rien de plus ou moins qu'une stratégie pour réduire la portée de ce que le programmeur doit comprendre afin de raisonner sur le programme.

Un autre côté du problème de savoir où ils sont utilisés est que vous pouvez vous retrouver avec des globaux en double - auquel cas les choses peuvent devenir vraiment bizarres car la plupart des programmes obtiennent et définissent var1 tandis que dans quelques endroits var2 est utilisé pour contenir les mêmes informations. Surtout lorsque plusieurs personnes travaillent sur le même code. Les IDE peuvent être utiles pour trouver une utilisation réduisant le coût des globaux, mais ils ne font rien pour les doublons.

Plus vous avez de globaux, plus il est difficile de garder une trace de ce qui se passe avec eux. Ils devraient être peu nombreux et espacés.

jmoreno
la source
En fin de compte, avoir des globaux mutables est une très mauvaise idée. La seule exception décente est lorsque vous travaillez dans des empreintes matérielles extrêmement étroites, comme avec la programmation intégrée. À tout le moins, les candidats à des programmes globaux en programmation régulière devraient être divisés en membres statiques de classes ou de modules, tout ce qui est modifiable devrait également être considéré comme un cas spécial, doublement ainsi lorsque vous travaillez dans un environnement multi-thread. Utilisation de verrouillage / futures / promesses ou d'une autre méthode de sécurité des threads / transactions. - Puisque personne d'autre ne l'a mentionné, voyez le problème des philosophes de la restauration.
ocodo
1
Il ne fait aucun doute que les threads peuvent rendre les globes mutables plus difficiles à utiliser, mais vous pouvez obtenir le même problème de base en raison d'événements. Je suis d'accord avec la suggestion de mettre ourlet en tant que membres statiques, et j'irais plus loin en disant que, idéalement, ils devraient être des membres statiques PRIVÉS.
jmoreno
3

Les deux problèmes avec les globaux et les singletons sont la testabilité et la déployabilité.

Pour les tests, j'ai vu trop de faisceaux de tests trop complexes juste pour faire face à des durées de vie mondiales et singleton mal planifiées. Assurez-vous qu'un tel objet a des règles de démarrage et de démontage claires et simples.

Quant à la déployabilité, il y a deux cas à considérer. Premièrement, comment vivra votre objet global? Est-ce dans une bibliothèque statique ou dynamique? Si cet objet global est réutilisé pour un plugin, obtiendrez-vous des copies supplémentaires? Deuxièmement, que se passe-t-il lorsque cet objet global est déposé dans une application parallèle? Est-il compatible avec les threads?

Dans l'ensemble, je pense que ces raisons signifient que les globales et les singletons ne sont utilisés qu'exceptionnellement.

smithco
la source
2

Le développement de systèmes embarqués critiques implique généralement l'utilisation de variables globales.

Les tailles de pile sont minuscules, tout est alloué statiquement ( malloc()est interdit), les variables globales sont cachées de l'extérieur de la bibliothèque à laquelle elles appartiennent.

mouviciel
la source
0

Dans une horrible base de code VB6 qui abuse des mondiaux comme s'il n'y avait pas de lendemain, je suis coupable d'en introduire une nouvelle:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Je pense que c'est l'un des rares cas d'utilisation valides pour un objet global.

Mathieu Guindon
la source