Je viens de croiser cette vieille question en demandant ce qui est si pervers à propos de l'état global, et la réponse acceptée avec le plus grand nombre de votes affirme que vous ne pouvez faire confiance à aucun code fonctionnant avec des variables globales, car un autre code situé ailleurs pourrait en modifier le contenu. valeur et vous ne savez pas quel sera le comportement de votre code car les données sont différentes! Mais quand je regarde cela, je ne peux pas m'empêcher de penser que c'est une explication vraiment faible, car en quoi est-ce différent de travailler avec des données stockées dans une base de données?
Lorsque votre programme utilise des données d'une base de données, vous ne vous souciez pas de savoir si un autre code de votre système le modifie, ou même si un programme complètement différent le modifie, d'ailleurs. Vous ne vous souciez pas de ce que les données sont; c'est le point entier. Tout ce qui compte, c'est que votre code traite correctement les données qu'il rencontre. (Évidemment, je passe sous silence la question souvent épineuse de la mise en cache ici, mais ignorons-le pour le moment.)
Mais si les données que vous utilisez proviennent d'une source externe sur laquelle votre code n'a aucun contrôle, tel qu'une base de données (ou une entrée utilisateur, ou une prise réseau, ou un fichier, etc.) et que rien ne se passe mal. Avec cela, comment les données globales contenues dans le code lui-même - sur lesquelles votre programme a un degré de contrôle beaucoup plus important - sont-elles un inconvénient quand elles sont évidemment bien moins mauvaises que des données parfaitement normales que personne ne considère comme un problème?
Réponses:
Premièrement, je dirais que la réponse que vous associez pour surestimer ce problème particulier et que le principal inconvénient de l'état global est qu'il introduit le couplage de manière imprévisible, ce qui peut rendre difficile le changement de comportement de votre système à l'avenir.
Mais pour approfondir davantage cette question, il existe des différences entre l’état global d’une application orientée objet typique et l’état conservé dans une base de données. En bref, les plus importants sont:
Les systèmes orientés objet permettent de remplacer un objet par une classe d'objet différente, à condition qu'il s'agisse d'un sous-type du type d'origine. Cela permet de modifier le comportement , pas seulement les données .
L'état global dans une application ne fournit généralement pas les garanties de cohérence élevées d'une base de données - il n'y a pas de transactions au cours desquelles vous voyez un état cohérent, pas de mises à jour atomiques, etc.
De plus, nous pouvons voir l'état de la base de données comme un mal nécessaire; il est impossible de l'éliminer de nos systèmes. L'état global, cependant, n'est pas nécessaire. Nous pouvons entièrement l'éliminer. Ainsi, même si les problèmes avec une base de données étaient aussi graves , nous pouvons toujours éliminer certains des problèmes potentiels et une solution partielle est préférable à l'absence de solution.
la source
Premièrement, quels sont les problèmes avec les variables globales, en fonction de la réponse acceptée à la question que vous avez liée?
Les bases de données sont, dans la grande majorité du temps, compatibles ACID. ACID traite spécifiquement des problèmes sous-jacents qui rendraient un magasin de données imprévisible ou peu fiable.
En effet, les variables globales existent dans une étendue très éloignée de leur utilisation, peut-être même dans un fichier différent. Lorsque vous utilisez une base de données, vous utilisez un jeu d'enregistrements ou un objet ORM local par rapport au code que vous lisez (ou devriez utiliser).
Les pilotes de base de données fournissent généralement une interface cohérente et compréhensible pour accéder à des données identiques quel que soit le domaine problématique. Lorsque vous obtenez des données d'une base de données, votre programme en possède une copie . Les mises à jour sont atomiques. Contraste avec les variables globales, où plusieurs threads ou méthodes peuvent fonctionner sur le même élément de données sans aucune atomicité, sauf si vous ajoutez vous-même la synchronisation. Les mises à jour des données sont imprévisibles et difficiles à repérer. Les mises à jour peuvent être entrelacées, ce qui entraîne la corruption des exemples de manuels multilingues (par exemple, des incréments entrelacés).
Les bases de données modélisent au départ des données différentes de celles des variables globales, mais, en laissant cela de côté, les bases de données sont conçues dès le départ pour être un magasin de données conforme à ACID qui atténue nombre des problèmes liés aux variables globales.
la source
Je ferais quelques observations:
Oui, une base de données est un état global.
En fait, comme vous l'avez souligné, il s'agit d'un état super mondial. C'est universel! Son champ d' action implique quelque chose ou quelqu'un qui se connecte à la base de données. Et je soupçonne que de nombreuses personnes avec des années d’expérience peuvent vous raconter des histoires horribles sur la façon dont des "choses étranges" dans les données ont conduit à un "comportement inattendu" dans une ou plusieurs des applications pertinentes ...
L'une des conséquences potentielles de l'utilisation d'une variable globale est que deux "modules" distincts utiliseront cette variable à leurs propres fins. Et dans cette mesure, une table de base de données n'est pas différente. Il peut être victime du même problème.
Hmm ... Voici la chose:
Si un module ne fonctionne pas de manière extrinsèque, il ne fait rien.
Un module utile peut recevoir des données ou le trouver . Et, il peut renvoyer des données ou modifier l’ état. Mais, si elle n'interagit pas avec le monde extérieur d'une manière ou d'une autre, elle pourrait également ne rien faire.
Nous préférons maintenant recevoir des données et les renvoyer . La plupart des modules sont simplement plus faciles à écrire s’ils peuvent être écrits avec un mépris total pour ce que fait le monde extérieur. Mais en fin de compte, il faut que les données soient trouvées et que cet état global et externe soit modifié .
De plus, dans les applications du monde réel, les données existent pour pouvoir être lues et mises à jour par diverses opérations. Certains problèmes sont évités par des verrous et des transactions. Toutefois, pour éviter que ces opérations ne se contredisent en principe , au bout du compte, il suffit simplement de réfléchir. (Et faire des erreurs ...)
Mais aussi, nous ne travaillons généralement pas directement avec l’état global.
Sauf si l'application réside dans la couche de données (en SQL ou autre), les objets avec lesquels travaillent nos modules sont en réalité des copies de l'état global partagé. Nous pouvons faire ce que nous voulons sans aucun impact sur l’état actuel partagé.
Et, dans les cas où nous devons muter cet état global, en supposant que les données qui nous ont été fournies n’ont pas changé, nous pouvons généralement effectuer le même verrouillage que celui que nous appliquerions à nos globaux locaux.
Et finalement, nous faisons habituellement avec les bases de données des choses différentes de celles que nous pourrions avoir avec des globals vilains.
Un vilain global brisé ressemble à ceci:
Nous n'utilisons tout simplement pas de bases de données pour des tâches en cours de traitement / opérationnelles de ce type. Et c’est peut-être la nature lente de la base de données et la commodité relative d’une simple variable qui nous découragent: notre interaction lente et délicate avec les bases de données en fait tout simplement de mauvais candidats pour de nombreuses erreurs que nous avons commises avec des variables.
la source
Je ne suis pas d'accord avec l'affirmation fondamentale selon laquelle:
Ma pensée initiale était "Wow. Just Wow". Tant de temps et d'efforts sont consacrés à éviter exactement cela - et à déterminer quels compromis et compromis fonctionnent pour chaque application. Ignorer cela est une recette pour un désastre.
Mais je fais aussi de la diasgree sur le plan architectural. Une variable globale n'est pas simplement un état global. C'est un état global qui est accessible de n'importe où de manière transparente. Contrairement à l'utilisation d'une base de données, vous devez disposer d'un descripteur - (à moins que vous ne stockiez qu'un descripteur dans une variable globale ...)
Par exemple, utiliser une variable globale pourrait ressembler à ceci
Mais faire la même chose avec une base de données devrait être plus explicite sur ce qu’il fait.
La base de données on est évidemment en train de mettre la main dessus. Si vous ne souhaitez pas utiliser de base de données, vous pouvez utiliser un état explicite qui ressemble à peu près au cas de la base de données.
Donc, je dirais que l'utilisation d'une base de données revient beaucoup plus à utiliser un état explicite qu'à utiliser des variables globales.
la source
MakeNewThing
dépend deMakeNewThingInDb
et que ma classe de contrôleur utiliseMakeNewThing
, le code de mon contrôleur n'indique pas clairement que je modifie la base de données. Alors, que se passe-t-il si j'utilise une autre classe qui valide réellement ma transaction en cours dans la base de données? DI rend très difficile le contrôle de la portée d'un objet.Le fait que la seule raison pour laquelle les variables globales ne puissent pas être approuvées étant donné que l'état peut être modifié ailleurs n'est pas, en soi, une raison suffisante pour ne pas les utiliser, a convenu (c'est une très bonne raison cependant!). Il est probable que la réponse consistait principalement en une utilisation où il serait plus logique de limiter l'accès d'une variable à des zones de code concernées.
Les bases de données sont une autre affaire, cependant, car elles sont conçues pour être accessibles «globalement» pour ainsi dire.
Par exemple:
Mais surtout, les bases de données ont un objectif différent de celui d’une variable globale. Les bases de données permettent de stocker et de rechercher de grandes quantités de données organisées, où les variables globales servent des niches spécifiques (lorsque cela est justifiable).
la source
Ou différent du travail avec un périphérique interactif, avec un fichier, avec une mémoire partagée, etc. Un programme qui fait exactement la même chose à chaque fois qu'il s'exécute est un programme très ennuyeux et plutôt inutile. Alors oui, c'est un argument faible.
Pour moi, la différence qui fait la différence en ce qui concerne les variables globales est qu’elles forment des lignes de communication cachées et non protégées. La lecture à partir d'un clavier est très évidente et protégée. Je dois effectuer un certain appel de fonction et je ne peux pas accéder au pilote du clavier. Il en va de même pour l'accès aux fichiers, la mémoire partagée et votre exemple, les bases de données. Il est évident pour le lecteur du code que cette fonction lit à partir du clavier, que cette fonction accède à un fichier, qu'une autre fonction accède à la mémoire partagée (et qu'il serait préférable de la protéger), et qu'une autre fonction accède à une base de données.
Avec les variables globales, en revanche, ce n’est pas évident du tout. L'API dit d'appeler
foo(this_argument, that_argument)
. Rien dans la séquence d'appel n'indique que la variable globaleg_DangerWillRobinson
doit avoir une valeur quelconque avant d'appelerfoo
(ou d'être examinée après l'appelfoo
).Google a interdit l'utilisation d'arguments de référence non const en C ++, principalement parce que cela n'est pas évident pour le lecteur du code qui
foo(x)
va changer,x
car celafoo
prend comme argument une référence non constante. (Comparez avec C #, qui indique que la définition de la fonction et le site d'appel doivent qualifier un paramètre de référence avec leref
mot clé.) Bien que je ne sois pas d'accord avec la norme Google à ce sujet, je comprends leur argument.Le code est écrit une fois et modifié plusieurs fois, mais s'il est bon, il est lu beaucoup de fois. Les lignes de communication cachées sont un très mauvais karma. La référence non constante de C ++ représente une ligne de communication cachée mineure. Une bonne API ou un bon IDE me montrera que "Oh! C'est un appel par référence." Les variables globales constituent une énorme voie de communication cachée.
la source
Je pense que l'explication citée simplifie à l'extrême le problème au point que le raisonnement devient ridicule. Bien entendu, l'état d'une base de données externe contribue à l'état global. La question importante est de savoir commentvotre programme dépend de l'état global (mutable). Si une fonction de bibliothèque permettant de scinder des chaînes sur un espace blanc dépend des résultats intermédiaires stockés dans une base de données, je m'opposerais à cette conception au moins autant que je le ferais à un tableau de caractères global utilisé dans le même but. D'autre part, si vous décidez que votre application n'a pas besoin d'un SGBD complet pour stocker les données de l'entreprise à ce stade et qu'une structure clé-valeur globale en mémoire suffira, ce n'est pas nécessairement le signe d'une conception médiocre. Ce qui est important, c’est que, quelle que soit la solution choisie pour stocker vos données, ce choix s’applique à une très petite partie du système, de sorte que la plupart des composants peuvent rester indépendants de la solution choisie pour le déploiement, et être testés dans des unités isolées et déployées. La solution peut être changée ultérieurement avec peu d'effort.
la source
En tant qu’ingénieur logiciel travaillant principalement avec des microprogrammes intégrés, j’utilise presque toujours des variables globales pour tout ce qui se passe entre les modules. En fait, c'est la meilleure pratique pour les systèmes intégrés. Ils sont attribués de manière statique, il n'y a donc aucun risque d'explosion du tas / de la pile et aucun temps supplémentaire n'est alloué pour l'allocation / le nettoyage de la pile à l'entrée / à la sortie de la fonction.
L'inconvénient est que nous ne devons considérer la façon dont ces variables sont utilisées, et beaucoup de ce qui revient au même genre de pensée qui va dans la base de données-tiraillements. Toute lecture / écriture asynchrone de variables DOIT être atomique. Si plusieurs emplacements peuvent écrire une variable, vous devez vous assurer qu'ils écrivent toujours des données valides, de sorte que l'écriture précédente ne soit pas remplacée de manière arbitraire (ou que le remplacement arbitraire soit une chose sûre à faire). Si la même variable est lue plus d'une fois, il faut réfléchir à ce qui se passe si la variable change de valeur entre les lectures, ou une copie de la variable doit être prise au début de sorte que le traitement soit effectué en utilisant une valeur cohérente, même si cette valeur devient périmée pendant le traitement.
(Pour ce dernier, le tout premier jour de mon contrat de travail sur un système de contre-mesures pour aéronefs, qui était tellement lié à la sécurité, l'équipe des logiciels examinait un rapport de bogue qu'ils essayaient de résoudre depuis environ une semaine. J'avais eu juste le temps de télécharger les outils de développement et une copie du code. Je lui ai demandé "Cette variable ne peut-elle pas être mise à jour entre les lectures et ce qui le cause?", Mais je n'ai pas vraiment eu de réponse. Alors, pendant qu'ils en discutaient encore, j'ai ajouté un code de protection pour lire la variable de manière atomique, une génération locale et en gros je me suis dit "hé les gars, essayez ceci". :)
Les variables globales ne sont donc pas une mauvaise chose sans équivoque, mais elles vous laissent faire face à un large éventail de problèmes si vous n'y réfléchissez pas attentivement.
la source
En fonction de l'aspect que vous jugez, les variables globales et l'accès à la base de données peuvent être des mondes à part, mais tant que nous les jugeons comme des dépendances, ils sont identiques.
Considérons la définition par la programmation fonctionnelle d'une fonction pure, selon laquelle elle dépend uniquement des paramètres qu'elle prend en entrée, produisant une sortie déterministe. En d'autres termes, si le même jeu d'arguments est répété deux fois, il doit produire le même résultat.
Lorsqu'une fonction dépend d'une variable globale, elle ne peut plus être considérée comme pure, car, pour le même ensemble ou les mêmes arguments, elle peut générer des résultats différents, car la valeur de la variable globale peut avoir changé entre les appels.
Cependant, la fonction peut toujours être considérée comme déterministe si nous considérons la variable globale comme une partie de l'interface de la fonction au même titre que ses autres arguments. Ce n'est donc pas le problème. Le problème est seulement que cela est caché jusqu'au moment où nous sommes surpris par un comportement inattendu de fonctions apparemment évidentes, puis allez lire leurs implémentations pour découvrir les dépendances cachées .
Cette partie, le moment où une variable globale devient une dépendance cachée est ce qui est considéré comme un mal par nos programmeurs. Cela rend le code plus difficile à raisonner, à prédire comment il va se comporter, difficile à réutiliser, difficile à tester et surtout, cela augmente le temps de débogage et de résolution du problème lorsqu'un problème survient.
La même chose se produit lorsque nous masquons la dépendance à la base de données. Nous pouvons avoir des fonctions ou des objets appelant directement des requêtes et des commandes de base de données, masquant ces dépendances et nous causant exactement le même problème que les variables globales; ou nous pouvons les rendre explicites, ce qui, en fin de compte, est considéré comme une meilleure pratique qui porte plusieurs noms, tels que modèle de référentiel, magasin de données, passerelle, etc.
PS: Il existe d’autres aspects importants pour cette comparaison, par exemple le fait qu’il s’agisse d’une concurrence ou non, mais ce point est couvert par d’autres réponses ici.
la source
Bon, commençons par le point historique.
Nous sommes dans une ancienne application, écrite dans votre mélange typique d'assemblage et de C. Il n'y a pas de fonctions, juste des procédures . Lorsque vous souhaitez passer un argument ou une valeur de retour d'une procédure, vous utilisez une variable globale. Inutile de dire que c’est assez difficile à suivre, et en général, chaque procédure peut faire ce qu’elle veut avec chaque variable globale. Sans surprise, les utilisateurs ont eu tendance à passer des arguments et à renvoyer des valeurs d'une manière différente dès que c'était faisable (à moins que cela ne soit pas critique en termes de performances - consultez par exemple le code source de Build Engine (Duke 3D)). La haine des variables globales est née ici: vous aviez très peu idée de la portion d'état global que chaque procédure lirait et modifierait, et vous ne pouviez pas vraiment imbriquer les appels de procédure en toute sécurité.
Cela signifie-t-il que la haine de variable globale fait partie du passé? Pas assez.
Tout d'abord, je dois mentionner que j'ai vu exactement la même approche pour passer des arguments dans le projet sur lequel je travaille actuellement. Pour passer deux instances de type de référence en C #, dans un projet vieux d'environ 10 ans. Il n'y a littéralement aucune bonne raison de le faire ainsi, et est probablement né de la culture de la cargaison ou d'un malentendu complet sur le fonctionnement de C #.
Le point le plus important est qu'en ajoutant des variables globales, vous élargissez la portée de chaque morceau de code ayant accès à cette variable globale. Vous vous souvenez de toutes ces recommandations telles que "gardez vos méthodes courtes"? Si vous avez 600 variables globales (encore une fois, exemple concret: /), toutes les étendues de vos méthodes sont implicitement développées par ces 600 variables globales. Il n'existe pas de moyen simple de savoir qui a accès à quoi.
Si cela est mal fait (comme d'habitude :)), les variables globales peuvent avoir un couplage entre elles. Mais vous ne savez pas comment ils sont couplés et il n'existe aucun mécanisme pour garantir la cohérence de l'état global. Même si vous introduisez des sections critiques pour essayer de garder les choses cohérentes, vous constaterez que cela se compare mal à une base de données ACID appropriée:
Est-il possible de résoudre ces problèmes? Pas vraiment. Vous avez besoin d'encapsulation pour gérer cela, ou d'une discipline très stricte. Il est difficile de bien faire les choses et ce n’est généralement pas une très bonne recette pour réussir en développement logiciel :)
Une portée plus petite a tendance à rendre le code plus facile à raisonner. Les variables globales font que même les éléments de code les plus simples incluent d’énormes pans de portée.
Bien sûr, cela ne signifie pas que la portée mondiale est un mal. Cela ne devrait tout simplement pas être la première solution que vous choisissez: c’est un exemple typique de «simple à mettre en œuvre, difficile à maintenir».
la source
Une variable globale est un outil, il peut être utilisé pour le bien et pour le mal.
Une base de données est un outil, il peut être utilisé pour le bien et pour le mal.
Comme le note l’affiche originale, la différence n’est pas si grande.
Les étudiants inexpérimentés pensent souvent que les insectes sont quelque chose qui arrive à d'autres personnes. Les enseignants utilisent "Les variables globales sont pervers" comme une raison simplifiée pour pénaliser les mauvais designs. Généralement, les étudiants ne comprennent pas que le fait que leur programme de 100 lignes soit exempt de bogues ne signifie pas que les mêmes méthodes peuvent être utilisées pour des programmes de 10 000 lignes.
Lorsque vous travaillez avec des bases de données, vous ne pouvez pas simplement interdire l’état global car c’est la raison d’être du programme. Au lieu de cela, vous obtenez des instructions plus détaillées telles que ACID et les formulaires normaux, etc.
Si les personnes utilisaient l'approche ACID pour les variables globales, elles ne seraient pas si mauvaises.
D'autre part, si vous concevez mal les bases de données, elles peuvent être cauchemardesques.
la source
Pour moi, le principal mal est que Globals n’ait aucune protection contre les problèmes de concurrence. Vous pouvez ajouter des mécanismes pour traiter de tels problèmes avec Globals, mais vous constaterez que plus vous résolvez de problèmes de simultanéité, plus vos globes commencent à imiter une base de données. Le mal secondaire n'est pas un contrat d'utilisation.
la source
errno
dans C.Certaines des autres réponses tentent d'expliquer pourquoi l'utilisation d'une base de données est bonne. Ils ont tort! Une base de données est un état global et, en tant que telle, est aussi diabolique qu'un singleton ou une variable globale. Utiliser une base de données est une mauvaise chose quand vous pouvez facilement utiliser une carte locale ou un tableau à la place!
Les variables globales permettent un accès global, ce qui comporte un risque d'abus. Les variables globales ont également des avantages. On dit généralement que les variables globales sont quelque chose que vous devriez éviter, pas quelque chose que vous ne devriez jamais utiliser. Si vous pouvez facilement les éviter, vous devriez les éviter. Mais si les avantages l'emportent sur les inconvénients, vous devez bien sûr les utiliser! *
La même chose ** s'applique aux bases de données, qui sont à l'état global - tout comme les variables globales. Si vous pouvez vous débrouiller sans accès à une base de données et que la logique qui en résulte fait tout ce dont vous avez besoin et est tout aussi complexe, l'utilisation d'une base de données augmente les risques pour votre projet, sans aucun avantage correspondant.
Dans la réalité, de nombreuses applications nécessitent un état global de conception, parfois même un état global persistant - c'est pourquoi nous avons des fichiers, des bases de données, etc.
* L'exception ici sont les étudiants. Il est logique d’interdire aux étudiants d’utiliser des variables globales afin d’apprendre quelles sont les alternatives.
** Certaines réponses prétendent à tort que les bases de données sont mieux protégées que d'autres formes d'état global (la question concerne explicitement l'état global , pas seulement les variables globales). C'est des conneries. La protection principale offerte dans le scénario de base de données est par convention, ce qui est identique pour tout autre état global. La plupart des langages offrent également une protection supplémentaire pour l’état global, sous la forme de
const
classes qui ne permettent tout simplement pas de modifier leur état après qu’il a été défini dans le constructeur, ou d’objecteurs et de paramètres qui peuvent prendre en compte les informations de thread ou l’état du programme.la source
En un sens, la distinction entre les variables globales et une base de données est similaire à la distinction entre les membres privés et publics d'un objet (en supposant que quiconque utilise encore des champs publics). Si vous considérez l'ensemble du programme comme un objet, les variables globales sont les variables privées et la base de données, les champs publics.
La distinction essentielle en est une de responsabilité assumée.
Lorsque vous écrivez un objet, il est supposé que toute personne qui gère les méthodes de membre veillera à ce que les champs privés restent bien gérés. Mais vous renoncez déjà à toute hypothèse sur l'état des champs publics et les traitez avec un soin particulier.
La même hypothèse s’applique à un niveau plus large à la base de données globals v / s. En outre, le langage / écosystème de programmation garantit les restrictions d’accès aux v / s privés publics de la même manière qu’il les applique à la base de données v / s de globals (mémoire non partagée).
Lorsque le multithreading entre en jeu, le concept de base de données v / s global v / s privé v / s public n'est que des distinctions le long d'un spectre.
la source
Une base de données peut être un état global, mais il n'est pas nécessaire qu'elle le soit tout le temps. Je suis en désaccord avec l'hypothèse que vous n'avez pas le contrôle. Un moyen de gérer cela est le verrouillage et la sécurité. Cela peut être fait à l'enregistrement, la table ou la base de données entière. Une autre approche consiste à créer une sorte de champ de version qui empêcherait la modification d’un enregistrement si les données sont périmées.
Comme une variable globale, les valeurs d'une base de données peuvent être modifiées une fois qu'elles sont déverrouillées, mais il existe de nombreuses façons de contrôler l'accès (Ne donnez pas le mot de passe à tous les développeurs pour le compte autorisé à modifier les données.). Si vous avez une variable dont l'accès est limité, ce n'est pas très global.
la source
Il y a plusieurs différences:
Une valeur de base de données peut être modifiée à la volée. En revanche, la valeur d'un global définie dans le code ne peut être modifiée que si vous redéployez votre application et modifiez votre code. En fait, c'est intentionnel. Une base de données est pour les valeurs qui pourraient changer au fil du temps, mais les variables globales devraient seulement être pour des choses qui ne changeront jamais et quand ils ne contiennent pas de données réelles.
Une valeur de base de données (ligne, colonne) a un contexte et un mappage relationnel dans la base de données. Cette relation peut être facilement extraite et analysée à l'aide d'outils comme Jailer (par exemple). Une variable globale, en revanche, est légèrement différente. Vous pouvez trouver tous les usages, mais il vous serait impossible de me dire toutes les manières dont la variable interagit avec le reste de votre monde.
Les variables globales sont plus rapides . Obtenir quelque chose d'une base de données nécessite une connexion à la base de données, une sélection à mon exécution, puis la connexion à la base de données doit être fermée. Toutes les conversions dont vous pourriez avoir besoin s’ajoutent à cela. Comparez cela à un accès global dans votre code.
Ce sont les seuls auxquels je puisse penser pour le moment, mais je suis sûr qu'il y en a plus. En termes simples, il s’agit de deux choses différentes qui doivent être utilisées pour des objectifs différents .
la source
Bien sûr, les globals ne sont pas toujours inappropriés. Ils existent parce qu'ils ont un usage légitime. Le principal problème des globals, et la principale source d'avertissement pour les éviter, est qu'un code utilisant un global est associé à celui-ci et à un seul.
Par exemple, considérons un serveur HTTP stockant le nom du serveur.
Si vous stockez le nom du serveur dans un fichier global, le processus ne peut pas simultanément exécuter la logique pour deux noms de serveur différents. Peut-être que la conception d'origine n'avait jamais envisagé d'exécuter plus d'une instance de serveur à la fois, mais si vous décidez plus tard de le faire, vous ne pourrez tout simplement pas si le nom du serveur est global.
En revanche, si le nom du serveur est dans une base de données, il n'y a pas de problème. Vous pouvez simplement créer une instance de cette base de données pour chaque instance du serveur HTTP. Étant donné que chaque instance du serveur possède sa propre instance de la base de données, elle peut avoir son propre nom de serveur.
Donc, l'objection principale aux globales, il ne peut y avoir qu'une seule valeur pour tout le code qui accède à ce global, ne s'applique pas aux entrées de base de données. Le même code peut facilement accéder à des instances de base de données distinctes ayant des valeurs différentes pour une entrée particulière.
la source
Je pense que c’est une question intéressante, mais il est un peu difficile de répondre à cette question car deux problèmes principaux sont regroupés sous le terme «État mondial». Le premier est le concept de «couplage global». La preuve en est que l'alternative donnée pour l'état global est l'injection de dépendance. Le fait est que DI n'élimine pas nécessairement l'état global. En d'autres termes, il est tout à fait possible et courant d'injecter des dépendances sur un état global. Ce que fait DI, c'est enlever le couplage qui vient avec les variables globales et le motif Singleton couramment utilisé. Hormis une conception légèrement moins évidente, l'élimination de ce type de couplage présente très peu d'inconvénients et les avantages de cette suppression augmentent de manière exponentielle avec le nombre de dépendances sur ces globaux.
L'autre aspect de cet état est l'état partagé. Je ne sais pas s'il existe une distinction très nette entre un état partagé globalement et un état partagé en général, mais les coûts et les avantages sont beaucoup plus nuancés. En termes simples, il existe d'innombrables systèmes logiciels qui nécessitent un état partagé pour être utiles. Le bitcoin, par exemple, est un moyen très intelligent de partager un État de manière globale (littéralement) de manière décentralisée. Partager correctement un état mutable sans créer d’énormes goulets d’étranglement est difficile mais utile. Donc, si vous n'avez pas vraiment besoin de le faire, vous pouvez simplifier votre application en minimisant l'état mutable partagé.
Ainsi, la question de savoir comment les bases de données diffèrent des bases globales est également abordée sous ces deux aspects. Est-ce qu'ils introduisent le couplage? Oui, ils le peuvent, mais cela dépend beaucoup de la conception de l'application et de la conception de la base de données. Il y a trop de facteurs pour qu'une réponse unique puisse déterminer si les bases de données introduisent un couplage global sans détails de la conception. Quant à savoir s'ils introduisent le partage de l'état, eh bien, c'est en quelque sorte le point essentiel d'une base de données. La question est de savoir s'ils le font bien. Encore une fois, j'estime qu'il est trop compliqué de répondre sans de nombreuses autres informations telles que les alternatives et de nombreux autres compromis.
la source
J'y penserais un peu différemment: une "variable globale" comme un comportement est un prix payé par les administrateurs de base de données (DBA), car c'est un mal nécessaire pour faire leur travail.
Comme plusieurs autres personnes l'ont souligné, le problème des variables globales n'est pas arbitraire. Le problème est que leur utilisation rend le comportement de votre programme de moins en moins prévisible, car il devient plus difficile de déterminer qui utilise la variable et de quelle manière. C'est un gros problème pour les logiciels modernes, car on leur demande généralement de faire beaucoup de choses souples. Il peut faire des milliards, voire des trillions de manipulations d’états complexes au cours d’une course. La capacité de prouver de vraies déclarations sur ce que le logiciel fera dans ces milliards ou ces milliards d'opérations est extrêmement utile.
Dans le cas des logiciels modernes, toutes nos langues fournissent des outils d'aide, tels que l'encapsulation. Le choix de ne pas l'utiliser est inutile, ce qui conduit à la mentalité "les globals sont mauvais". Dans de nombreuses régions du domaine du développement logiciel, les seules personnes qui les utilisent sont des personnes qui ne savent pas mieux coder. Cela signifie qu'ils ne sont pas seulement des problèmes directement, mais ils suggèrent indirectement que le développeur ne savait pas ce qu'il faisait. Dans d’autres régions, vous constaterez que les globaux sont tout à fait normaux (les logiciels embarqués, en particulier, aiment les globals, en partie parce qu’ils fonctionnent bien avec les ISR). Cependant, parmi les nombreux développeurs de logiciels, ils sont la voix d'une minorité, de sorte que la seule voix que vous entendez est "les globals sont diaboliques".
Le développement de bases de données est l'une de ces situations de voix minoritaires. Les outils nécessaires pour faire un travail de DBA sont très puissants, et leur théorie est pas enracinée dans l' encapsulation. Pour exploiter chaque performance de leurs bases de données, ils ont besoin d'un accès complet et sans entrave à tout, à l'instar des globals. Utilisez l'une de leurs énormes bases de données de 100 millions de lignes (ou plus!), Et vous comprendrez pourquoi ils ne laissent pas leur moteur de base de données tenir le coup.
Ils paient un prix pour cela, un prix cher. Les DBA sont obligés d'être presque pathologiques par leur souci du détail, car leurs outils ne les protègent pas. Le meilleur moyen de protection est ACID ou peut-être des clés étrangères. Ceux qui ne sont pas pathologiques se retrouvent avec un fouillis de tables complètement inutilisable, voire corrompu.
Il n’est pas rare d’avoir des progiciels de 100 000 lignes. En théorie, n'importe quelle ligne du logiciel peut affecter n'importe quel type global à tout moment. Dans les administrateurs de base de données, vous ne trouvez jamais 100 000 requêtes différentes pouvant modifier la base de données. Il serait déraisonnable de maintenir l’attention portée aux détails pour vous protéger de vous-même. Si un administrateur de base de données a quelque chose d'important dans ce sens, il encapsulera intentionnellement sa base de données à l'aide d'accesseurs, en contournant les problèmes de type "global", puis effectuera le maximum de travail possible grâce à ce mécanisme "plus sûr". Ainsi, même lorsque la base de données est utilisée, les utilisateurs évitent les globals. Ils viennent tout simplement avec beaucoup de danger, et il existe des alternatives qui sont tout aussi fortes, mais pas aussi dangereuses.
Préférez-vous vous promener sur du verre brisé ou sur des trottoirs bien balayés, si toutes les autres choses sont égales? Oui, vous pouvez marcher sur du verre brisé. Oui, certaines personnes gagnent même leur vie en le faisant. Mais quand même, laissez-les simplement balayer le trottoir et passer à autre chose!
la source
Je pense que la prémisse est fausse. Il n'y a aucune raison qu'une base de données doive être un "état global" plutôt qu'un objet de contexte (très grand). Si vous vous liez à la base de données que votre code utilise via des variables globales ou des paramètres de connexion de base de données globaux fixes, il n’est pas différent et n’est pas moins dommageable que tout autre état global. D'autre part, si vous transmettez correctement un objet de contexte pour la connexion à la base de données, il s'agit simplement d'un état contextuel volumineux (et largement utilisé), et non d'un état global.
Mesurer la différence est simple: pouvez-vous exécuter deux instances de la logique de votre programme, chacune utilisant sa propre base de données, dans un seul programme / processus sans apporter de modifications invasives au code? Si tel est le cas, votre base de données n'est pas vraiment "globale".
la source
Les globaux ne sont pas mauvais. ils sont simplement un outil. La mauvaise utilisation des globaux est problématique, de même que l'utilisation abusive de toute autre fonction de programmation.
Ma recommandation générale est que les globals ne devraient être utilisés que dans des situations bien comprises et réfléchies, où d’autres solutions sont moins optimales. Plus important encore, vous voulez vous assurer que vous avez bien documenté les endroits où cette valeur globale peut être modifiée et que, si vous utilisez plusieurs méthodes d'exécution multithread, assurez-vous que l'accès aux transactions globales globales et à toutes les dépendances co-dépendantes est transactionnel.
la source
Motif en lecture seule et supposez que vos données ne sont pas à jour lorsque vous les imprimez. La file d'attente écrit ou gère les conflits d'une autre manière. Bienvenue au diable, vous utilisez la base de données globale.
la source