Je sais que le fait d'avoir des variables globales ou des classes singleton crée des cas qui peuvent être difficiles à tester / gérer et j'ai été obligé d'utiliser ces modèles dans le code, mais souvent vous devez expédier.
Y a-t-il donc des cas où des variables globales ou singletons sont réellement utiles dans le développement de jeux?
software-engineering
design-patterns
Ólafur Waage
la source
la source
Certainement une liste non exhaustive, mais voici:
Les inconvénients
Soit pour ou contre
Avantages
Nous utilisons beaucoup une «structure de singletons mondiaux» dans nos titres de poche. Les titres de PC et de console ont tendance à moins compter sur eux; nous passerons davantage à une architecture événementielle / messagerie. Cela étant dit, les titres de PC / console utilisent encore souvent un TextureManager central; car il enveloppe généralement une seule ressource partagée (la mémoire de texture), cela a du sens pour nous.
Si vous maintenez votre API relativement propre, il pourrait ne pas être trop difficile de refactoriser un (ou un!) Modèle singleton lorsque vous en avez besoin ...
la source
Ils peuvent être très utiles, en particulier lors du prototypage ou de la mise en œuvre expérimentale, mais en général, nous préférons transmettre des références pour les structures de type gestionnaire, de cette façon, vous avez au moins un certain contrôle sur leur accès. Le plus gros problème avec les globaux et singletons (à mon avis) est qu'ils ne sont pas très conviviaux pour le multithread, et le code qui les utilise est beaucoup plus difficile à porter sur la mémoire non partagée, comme les SPU.
la source
Je dirais que le design singleton lui-même n'est pas utile du tout. Les variables globales peuvent certainement être utiles, mais je préfère les voir cachées derrière une interface bien écrite afin que vous ne soyez pas au courant de leur existence. Avec les singletons, vous êtes définitivement conscient de leur existence.
J'utilise souvent des variables globales pour les choses qui nécessitent un accès tout au long d'un moteur. Mon outil de performance est un bon exemple que j'utilise partout dans le moteur pour appeler. Les appels sont simples; ProbeRegister (), ProbeHit () et ProbeScoped (). Leur accès réel est un peu plus délicat et utilise des variables globales pour certaines de leurs choses.
la source
Le principal problème avec les globaux et les singletons mal implémentés est les bogues obscurs de construction et de déconstruction.
Donc, si vous travaillez avec des primitives qui n'ont pas ces problèmes ou qui sont très conscientes du problème avec un pointeur. Ensuite, ils peuvent être utilisés en toute sécurité.
Les globaux ont leur place, comme les gotos et ne doivent pas être rejetés d'emblée mais plutôt utilisés avec précaution.
Il y a une bonne explication à ce sujet dans le Google C ++ Style Guide
la source
Les globaux sont utiles tout en prototypant rapidement un système qui nécessite un certain état entre les appels de fonction. Une fois que vous avez établi que le système fonctionne, déplacez l'état dans une classe et transformez les fonctions en méthodes de cette classe.
Les singletons sont utiles pour vous causer des problèmes à vous-même et aux autres. Plus vous introduisez un état global, plus vous aurez de problèmes avec la correction, la maintenance, l'extensibilité, la simultanéité du code, etc. Ne le faites pas.
la source
J'ai tendance à recommander l'utilisation d'une sorte de conteneur DI / IoC avec gestion personnalisée de la durée de vie au lieu des singletons (même si vous utilisez un gestionnaire de durée de vie "à une seule instance"). Au moins, il est facile d'échanger l'implémentation pour faciliter les tests.
la source
Si vous voulez les fonctionnalités d'économie de mémoire d'un singleton, vous pouvez peut-être essayer le modèle de conception de poids mouche?
http://en.wikipedia.org/wiki/Flyweight_pattern
En ce qui concerne les problèmes multi-threads mentionnés ci-dessus, il devrait être assez simple avec une certaine prévoyance d'implémenter un mécanisme de verrouillage pour les ressources qui peuvent être partagées entre les threads. http://en.wikipedia.org/wiki/Read/write_lock_pattern
la source
Les singletons sont un excellent moyen de stocker un état partagé dans un premier prototype.
Ils ne sont pas une solution miracle et posent des problèmes, mais ils constituent un modèle très utile pour certains états de l'interface utilisateur / logique.
Par exemple, dans iOS, vous utilisez des singletons pour obtenir [UIApplication sharedApplication], dans cocos2d vous pouvez l'utiliser pour obtenir des références à certains objets comme [CCNotifications sharedManager] et personnellement, je commence généralement par un singleton [Game sharedGame] où je peux état de stockage partagé entre de nombreux composants différents.
la source
Wow, c'est intéressant pour moi, car je n'ai jamais personnellement eu de problème avec le motif singleton. Mon projet actuel est un moteur de jeu C ++ pour la Nintendo DS, et j'implémente de nombreux utilitaires d'accès au matériel (c.-à-d. VRAM Banks, Wifi, les deux moteurs graphiques) en tant qu'instances singleton, car ils sont destinés à envelopper le C mondial fonctions dans la bibliothèque sous-jacente.
la source
Uniquement lorsque vous avez un élément qui n'a qu'un seul contrôleur mais qui est géré par plusieurs modules.
Tels que, par exemple, l'interface de la souris. Ou interface joystick. Ou un lecteur de musique. Ou un lecteur audio. Ou l'écran. Ou le gestionnaire de fichiers de sauvegarde.
la source
Les globaux sont beaucoup plus rapides! Il conviendrait donc parfaitement à une application exigeante en performances, comme un jeu.
Les singletons sont un meilleur mondial, l'OMI, et donc le bon outil.
Utilisez-le avec parcimonie!
la source