Usar clases de "amigos" en el desarrollo del juego

9

Por lo general, en la velocidad de desarrollo del juego C ++ se valora más que la encapsulación, por lo tanto, se ve un montón de miembros de clase accesibles públicamente que realmente no deberían ser públicos.

Me parece encontrar en la mayoría de los casos que solo unas pocas clases muy selectas realmente necesitan conocer el funcionamiento interno de otras clases hasta el punto de modificar o leer sus datos privados.

La creación de getters / setters públicos para estos datos privados expone cosas que realmente no deberían modificarse de ninguna manera.

¿Sería un compromiso usar clases de amigos? o hay algún inconveniente en las clases de amigos que no estoy viendo.

David Young
fuente

Respuestas:

8

Hay dos inconvenientes principales para las clases de amigos.

  1. No puedes elegir lo que quieres exponer a tus amigos. Es todo o nada. Esto puede resultar problemático si está tratando de imponer el uso obligatorio de algún tipo de configurador no intrascendente.
  2. Sus dos clases ahora están un poco acopladas en el sentido de que el amigo sabe sobre el amigo.

Dicho esto, el uso de clases de amigos definitivamente puede mejorar la encapsulación, especialmente si la alternativa son los captadores / establecedores públicos.

Además, pregunta relacionada sobre SO: /programming/521754/when-to-use-friend-class-in-c

Tétrada
fuente
5

La encapsulación es agradable, pero la separación de preocupaciones es más agradable.

Una clase que accede a "alguna parte privada" de otra clase podría indicar que el código no está bien diseñado en primer lugar.

Cada vez que te encuentras en el lugar de "Dios mío, necesito hacer una clase de amigos aquí", la pregunta que debes hacerte es "¿Estoy haciendo esto correctamente o hay una forma más limpia?" (también conocido como "¿Esto me va a morder en el trasero más tarde?").

Si está seguro de la "amabilidad", póngalo allí sin dudarlo.

egarcia
fuente
Entiendo cómo usar una clase de amigo unirá estrechamente una clase con otra. Me preguntaba si había un patrón de diseño en particular que aliviara el problema, porque simplemente envolver algo en un getter / setter es potencialmente una solución peor.
David Young
1
Un ejemplo interesante es que el patrón Factory en C ++ requiere "amigo" debido al uso de constructores privados.
David Young
2

Otra opción es usar el lenguaje PIMPL , donde parte de la implementación de la estructura es un puntero a otro tipo. La mayoría de los usuarios de la clase solo incluirán el archivo de encabezado normal, donde la implementación es un puntero opaco. Las clases que necesitan acceso a los datos privados pueden incluir el encabezado que define el otro tipo y utilizar la interfaz que proporciona.

Este es un patrón común para los programadores de C que desean una funcionalidad similar a la de un amigo. En mi opinión, también se acerca más a pensar en la separación de preocupaciones (un principio de diseño generalmente bueno que conduce a un código ortogonal reutilizable) en lugar de encapsular (una técnica específica de OO que es útil para implementar la separación de preocupaciones, pero que a menudo también se usa mal complicar demasiado las cosas).

Tiene una ventaja sobre el amigo que no une al amigo con el amigo en absoluto. Algunas personas pueden afirmar que es una desventaja, ya que ahora cualquiera puede "hacer amigos" en su clase. Creo que es un miedo injustificado, ya que aún haces explícita la relación (al incluir el encabezado). Si tiene miedo de eso, tiene miedo de su capacidad (o la de su compañero de trabajo) para tomar decisiones arquitectónicas inteligentes. Pero si no puedes tomar esas decisiones correctamente más tarde, ¿por qué estás confiando en ti mismo friendahora?

Tiene una desventaja de costo de tiempo de ejecución. Al almacenar los datos en un puntero, tiene una peor coherencia de caché y más recuentos de asignación, y también necesita un destructor para limpiarlo.


fuente
+1 interesante, no he oído hablar de este concepto proveniente de un fondo Java.
David Young