Utilisation de classes «amis» dans le développement de jeux

9

Généralement, dans la vitesse de développement de jeux en C ++, la valeur est préférée à l'encapsulation, vous voyez donc une tonne de membres de classe accessibles au public qui ne devraient vraiment pas être publics.

Il semble que dans la plupart des cas, seuls quelques clases très sélectes ont vraiment besoin de connaître le fonctionnement interne d'une autre classe au point de modifier ou de lire leurs données privées.

La création de getters / setters publics pour ces données privées expose des choses qui ne devraient vraiment pas être modifiées à volonté.

Un compromis serait-il ici d'utiliser des classes d'amis? ou y a-t-il un inconvénient aux classes d'amis que je ne vois pas.

David Young
la source

Réponses:

8

Il y a deux inconvénients majeurs aux cours de friending.

  1. Vous ne pouvez pas choisir ce que vous souhaitez exposer à vos amis. C'est tout ou rien. Cela peut s'avérer problématique si vous essayez d'imposer l'utilisation obligatoire d'une sorte de setter non négligeable.
  2. Vos deux cours sont maintenant quelque peu couplés dans le sens où l'ami connaît l'ami.

Cela étant dit, l'utilisation de classes d'amis peut certainement améliorer l'encapsulation, surtout si l'alternative est les getters / setters publics.

Aussi, question connexe sur SO: /programming/521754/when-to-use-friend-class-in-c

Tetrad
la source
5

L'encapsulation est agréable, mais la séparation des préoccupations est plus agréable.

Une classe accédant à "une partie privée" d'une autre classe pourrait indiquer que le code n'est pas bien conçu en premier lieu.

Chaque fois que vous vous retrouvez dans la zone "ça alors, j'ai besoin de faire une classe d'amis ici", la question que vous devez vous poser est "est-ce que je fais ça correctement, ou y a-t-il une manière plus propre?" (aka "Est-ce que ça va me mordre dans le cul plus tard?").

Si vous êtes sûr de la "convivialité", mettez-la sans hésitation.

egarcia
la source
Je comprends que l'utilisation d'une classe d'amis couple étroitement une classe à l'autre. Je me demandais s'il y avait un modèle de conception en particulier qui atténue le problème, car simplement envelopper quelque chose dans un getter / setter est potentiellement une pire solution.
David Young
1
Un exemple intéressant est le modèle Factory en C ++ nécessite "ami" en raison de l'utilisation de constructeurs privés.
David Young
2

Une autre option consiste à utiliser l' idiome PIMPL , où une partie de l'implémentation de la structure est un pointeur vers un autre type. La plupart des utilisateurs de la classe incluront simplement le fichier d'en-tête normal, où l'implémentation est un pointeur opaque. Les classes qui ont besoin d'accéder aux données privées peuvent inclure l'en-tête définissant l'autre type et utiliser l'interface qu'il fournit.

C'est un modèle courant pour les programmeurs C qui souhaitent une fonctionnalité de type ami. À mon avis, cela permet également de réfléchir plus étroitement à la séparation des préoccupations (un principe de conception généralement bon qui conduit à un code orthogonal réutilisable) plutôt qu'à l'encapsulation (une technique spécifique à l'OO qui est utile pour mettre en œuvre la séparation des préoccupations, mais aussi souvent utilisée à mauvais escient). pour compliquer les choses).

Il a un avantage sur l'ami qu'il ne couple pas du tout l'ami à l'ami-ee. Certaines personnes pourraient prétendre que c'est un inconvénient, car maintenant, n'importe qui peut "amier" votre classe. Je pense que c'est une crainte injustifiée, car vous expliquez toujours la relation (en incluant l'en-tête). Si vous en avez peur, vous avez peur de votre capacité (ou celle de votre collègue) de prendre des décisions architecturales intelligentes. Mais si vous ne pouvez pas prendre ces décisions correctement plus tard, pourquoi vous faites-vous confiance friendmaintenant?

Il présente un inconvénient du coût d'exécution. En stockant les données dans un pointeur, vous obtenez une cohérence de cache plus faible et plus de comptes d'allocation, et vous avez également besoin d'un destructeur pour les nettoyer.


la source
+1 intéressant, je n'ai pas entendu parler de ce concept issu d'un background Java.
David Young