OK, la variable globale est condamnée, singleton est méprisé, Quelle est l'alternative?
pour les applications bureautiques, c'est-à-dire. C'est juste une question générale qui n'a peut-être besoin que de réponses générales.
9 réponses
Une classe statique avec des données membres statiques? Mais qui s'en soucie. Les membres de données statiques sont juste des variables globales avec un packaging plus politiquement correct.
ne laissez pas la mode outrepasser votre bon sens. Il n'y a rien de mal à utiliser une simple vieille variable globale. Le modèle singleton est souvent exagéré et ennuyeux à taper, et ennuyeux lorsque vous êtes simple pas à travers le code pour le déboguer.
en supposant que vous utilisez C / C++, je vous recommande de ne pas avoir variables globales qui sont des instances de classe qui attribuent de la mémoire à partir du tas. Ils rendront plus difficile pour vous d'utiliser des outils qui vérifient les fuites de mémoire. Déclarer le mondial comme un pointeur, de nouvelles au début de main(), supprimer à la fin.
modifier après 6 commentaires: Ne voudriez-vous pas être en mesure d'écrire une ligne à votre journal à partir de n'importe où dans votre application? Dans quelle mesure réalisez-vous concrètement cela sans qu'il y ait quelque chose de globalement visible pour faire cette journalisation? Si vous voulez quelque chose de globalement visible, alors allez de l'avant et le rendre globalement visible.
Réponse dépend de la langue. J'ai récemment rencontré un gars dont l'entreprise développe la pile USB qui fonctionne sur de nombreux téléphones cellulaires populaires (par exemple, afin que votre téléphone puisse parler à votre ordinateur). Ils ont une règle dans leur atelier que toutes les procédures C doivent être rentrantes. Dans la pratique, cela signifie qu'au lieu de variables globales, ils utilisent un paramètre supplémentaire pour chaque routine; le paramètre indique l'état qui devrait persister entre routines.
j'utilise cette technique tout le temps pour abstractions avec l'état. Exemple: abstraction du lecteur pour les images photographiques: le lecteur donne accès à un pixel à la fois; il doit connaître le descripteur de fichier ouvert, Quelle est la position actuelle dans l'image, etc. Toutes ces informations vont dans une structure c privée ou dans les membres privés d'une Classe C++. Pas de variables globales. Le monde extérieur voit:
typedef struct Pnmrdr_T *Pnmrdr_T;
struct Pnmrdr_T *Pnmrdr_new(FILE *);
pixel Pnmrdr_get(Pnmrdr_T);
void Pnmrdr_close(Pnmrdr_T);
void Pnmrdr_free(Pnmrdr_T *rp); // frees memory and sets *rp = NULL
ce style de programmation est très similaire aux méthodes OO.
pourquoi mieux que les variables globales? Il n'y a pas de surprises. Si quelque chose va mal ou si vous souhaitez ajouter une fonctionnalité, vous savez que tout est explicite dans les valeurs transmises. De plus, vous savez que vous pouvez brancher beaucoup de modules ensemble et qu'ils n'interféreront pas à moins que vous passiez explicitement l'état entre eux. Mon contact dans le domaine du téléphone cellulaire dit que cette propriété a été énorme pour son entreprise---ils sont un équipement logiciel OEM et ils peuvent facilement brancher différents morceaux ensemble pour différents clients.
j'ai vraiment comme programmer de cette façon parce que j'arrive à voir tout ce qui se passe, et mes structures de données privées sont protégées des regards indiscrets: -)
tout d'abord, il n'y a pas de raison de prétendre que les singles sont d'une façon ou d'une autre meilleurs ou plus acceptables que les globals. Un singleton est juste un global habillé pour ressembler à un OOP. Avec un tas d'autres problèmes lancés dans.
Et la solution est, bien sûr avoir des données globales. Au lieu que votre classe accède à une variable statique (globale) quelque part, passez les données à son constructeur. Oui, cela signifie que vous devez ajouter quelques arguments pour le constructeur, mais est-ce une mauvaise chose? Il rend les dépendances de la classe explicite. Je peux tester la classe simplement en lui fournissant différents objets dans le constructeur, alors que si elle s'appuie sur des données globales, ces globals doivent exister dans mon test, ce qui est compliqué.
de la même façon, je peux facilement reformater, parce qu'il n'y a pas de dépendance magique sur les classes autres que ce qui est passé directement à l'objet.
la sécurité des threads devient plus facile à gérer car vous n'avez plus tous vos objets communiquer avec la même instance globale. Au lieu de cela, ils peuvent être passés des instances séparées de la classe.
Je m'en fiche si les variables simples ou globales ne sont pas recommandées. Si je pense que c'est la façon la plus logique de le mettre en œuvre, alors je vais aller de l'avant et l'utiliser.
Cela dépend entièrement du problème que vous essayez de résoudre. Cette information clé a été omise par vous. Si vous cherchez une solution, il n'y en a pas. Il y a simplement des modèles que nous appliquons le cas échéant.
la préoccupation la plus commune que j'ai vu avec les globals et les singleton est que vous risquez un mauvais comportement en utilisant des fils. Dans ce cas, vous devez toujours utiliser l'exécution scope comme unité de base. C'est l'un des points forts de la programmation OO - vous pouvez utiliser les membres de l'objet pour conserver toutes les données pertinentes avec très peu de crainte de l'éclatement accidentel du fil. Ceci est en contraste avec un langage de programmation non-oo-capable, où vous auriez à transmettre des données via des paramètres.
Les autres les préoccupations communes ont tendance à être d'ordre organisationnel - il est difficile de comprendre exactement d'où viennent les données dans un grand système lorsqu'elles peuvent être lues ou écrites à n'importe quel moment. D'après mon expérience, c'est plus un problème avec le développeur qu'avec le code lui-même. À moins que vous ne travailliez sur l'un de ces mégasystèmes de cent millions de lignes qui semblent apparaître principalement dans la programmation des livres comme des exemples de problèmes difficiles, vous allez être en mesure de rechercher votre code entier pour un élément particulier dans un période de temps relativement court. La prochaine étape nécessaire consiste à vérifier régulièrement la base de codes pour s'assurer que les variables globales/statiques ne sont pas attribuées au hasard. C'est un anathème pour beaucoup d'approches de développement, mais pour des systèmes d'une certaine taille et d'une certaine complexité, c'est une solution parfaitement réalisable.
une solution courante à cela est d'utiliser des classes à instance unique au lieu des variables singleton/global.
Votre demande sera responsable de s'assurer que vous avez une seule instance.
Cette solution craint un peu parce que vous ne pouvez pas empêcher les gens d'instancier votre classe (n'est pas un singleton) donc il doit s'agir d'une classe interne.
Je ne me soucierais pas trop de tout le guerres de religion à propos du modèle singleton cependant-si je pense que cela correspond à mes besoins je l'utilise généralement.
les variables globales sont très bien dans les petits programmes, mais quand elles deviennent plus grosses, vous commencez à avoir des effets secondaires bizarres quand quelqu'un fait un changement ou corrige un bug en disant "oh, je vais juste régler ce global et le problème disparaît"
après avoir utilisé des globals et des Singleton et vu que tout était en ordre, j'ai trouvé cette solution.
faire chaque variable globale d'un membre d'une classe. Logiquement, chaque variable globale appartient à l'application (ou au système). créez juste une classe d'application. définir les objets comme des propriétés. ils sont donc créés dès le premier appel.
créer une classe singleton pour application, de sorte que vous puissiez y accéder globalement. Ce sera le seul singleton dans votre code. eh bien, à la fin c'est comme système.out or system.dans les objets en java.
note: je sais que c'est une très vieille question, mais encore populaire.