2009-03-22 17 views
5

Tengo una clase con muchos miembros de tipo incorporado con acceso de lectura/escritura. ¿Debo hacerlos miembros públicos y proporcionar métodos get/set para cada uno? ¿Qué hay de las estructuras?Accesodores contra miembros públicos

Respuesta

13

Si hay invariants necesita conservar, entonces sí. De lo contrario, no te molestes.

+1

Para los detractores: tomé el consejo del propio Stroustrup: http://www.artima.com/intv/goldilocks3.html "Bjarne Stroustrup: Mi regla de oro es que debes tener una clase real con una interfaz y un oculto representación si y solo si puedes considerar un invariante para la clase ". –

+0

Es definitelly. Más adelante en el mismo texto: "Sí. Si cada dato puede tener algún valor, entonces no tiene mucho sentido tener una clase. Tome una sola estructura de datos que tenga un nombre y una dirección. Cualquier cadena es un buen nombre, y cualquier cadena es una buena dirección. Si eso es lo que es, es una estructura. –

+0

Continuación: "No tiene nada privado. No hagas nada tonto como tener un nombre oculto y un campo de dirección con las funciones get_name y set_address y get_name y set_name. O aún peor, cree una clase base virtual con las funciones virtuales get_name y set_name, y así sucesivamente. " –

4

En primer lugar, si su clase tiene muchos mamebers de datos, probablemente no esté bien diseñada. Es posible que deba considerar dividirlo en varias clases o almacenar los datos en estructuras tales como mapas.

En cuanto a la provisión de acceso, la pregunta es ¿alguna vez querrá modificar el acceso, posiblemente evitándolo? Si la respuesta es sí, entonces necesita las funciones de acceso. Por otro lado, si tu clase es solo una bolsa de bits, sin comportamiento, entonces hazla una estructura.

0

El uso de métodos get/set para miembros de datos privados/protegidos es un mal diseño.

Hace que el código del cliente dependa de los detalles de implementación de su clase.

Los cambios en su clase provocan cambios en el código del cliente.

Sin embargo, se pueden usar métodos get/set para miembros públicos. Pero siempre es bueno evitarlos.

+0

¿Por qué -3 downvoting? – anand

+1

Lo reventé, por lo que fue al menos 4 votos negativos :) En serio, pensé que era de conocimiento común que los getters/setters son un mal diseño. De miedo. –

+0

¿Bien, la pregunta es si se pueden usar getter/setters? Es un mal diseño la mayoría de las veces y eso es lo que respondí. De la mayoría de las respuestas anteriores es la misma conclusión. No estoy seguro de que sea un conocimiento común para todos. – anand

19

Todo el motivo para tener accesadores (getters) y modificadores (setters) es proporcionarse un nivel adicional de indirección.

Este nivel adicional de direccionamiento indirecto le permite proporcionar una vista de solo lectura de su variable a una interfaz pública, sin permitir que se modifique su miembro de datos. Aún puedes usar un setter privado o protegido.

Los ajustadores le permiten realizar comprobaciones, validaciones y correcciones de error especiales cuando se establece un valor. Por ejemplo, setDirectory (const std :: string & strPath), puede asegurarse de que haya una barra de destino si el usuario no especificó una. Esto asegura que su estado de clase siempre será válido.

Los recolectores también pueden proteger a sus miembros de tenerlos expuestos para permitir que los punteros a ellos. Al no permitirles que los señalen desde el exterior, puede asegurarse de que si su objeto queda fuera del alcance no provocará un bloqueo.

El nivel adicional de indirección para getters/setters también le permite poder cambiar el miembro de datos que encapsula.

Con un getter también puede obtener diferentes vistas de sus datos, por ejemplo: getMinutes, cuando su miembro de datos se almacena realmente en segundos.

Esta no es la razón para usarlos, pero un buen efecto secundario del uso de getters y setters es que puede establecer un punto de interrupción dentro de su modificador, por ejemplo, para ver exactamente cuándo se cambia.

Ya sea que los use o no, es una decisión basada en su necesidad. Si tiene tantos miembros que es un gran dolor proporcionar getters y configuraciones, podría considerar almacenar los miembros de datos en una estructura y usar esa estructura dentro de su clase. Incluso podría proporcionar getters/setters para un objeto para toda la estructura a la vez.

1

Debe utilizar miembros de datos públicos sólo

  • en las estructuras, que no exponga al código de cliente (por ejemplo.obligar al estilo funtores) - es inútil para proteger las estructuras que nadie fuera alguna vez obtenga
  • si sus tipos encapsulan la lógica del sistema/de conseguir ellos (por ejemplo, si se crea un ObservableAttribute clase)
  • si son const miembros. en una estructura inmutable (no se puede hacer mucho, excepto para leerlos si son inmutables)

Si crea un miembro de datos públicos, tiene que estar seguro de que su valor es totalmente ortogonal con otros miembros de la clase. Ej., Deshabilita las posibilidades futuras de

  • observación de los cambios en el miembro
  • haciendo que el miembro de jugar algún papel en la clase invariante
  • inhabilitación del acceso al miembro
  • cambiar la implementación del miembro (por ejemplo. computarizada frente a frente en caché almacenada) si el rendimiento que necesita
Cuestiones relacionadas