¿TODAS sus variables deben ser declaradas privadas? [duplicar]

14

Sé que es una buena práctica mantenerse a salvo, y que siempre debemos evitar que otros accedan directamente a las propiedades de una clase. Escucho esto todo el tiempo de los profesores universitarios, y también lo veo todo el tiempo en un montón de código fuente publicado en el App Hub . De hecho, los profesores dicen que realmente quitarán marcas por cada variable que se declare pública.

Ahora, esto me deja siempre declarando las variables como privadas. No importa qué. Incluso si cada una de estas variables tuviera tanto un getter como un setter.

Pero aquí está el problema: es un trabajo tedioso. Tiendo a perder rápidamente el interés en un proyecto cada vez que necesito tener una variable en una clase que simplemente podría haber sido declarada pública en lugar de privada con un captador y un establecedor.

Entonces, mi pregunta es, ¿realmente necesito declarar todas mis variables como privadas? ¿O podría declarar públicas algunas variables cuando requieran un getter y un setter?

    
pregunta skizeey 13.03.2011 - 09:24

10 respuestas

19

Los profesores que dicen "SIEMPRE hacer esto o aquello" con respecto a la programación deben ser despedidos, o regresar a la escuela ellos mismos. En la programación, nunca hay una sola manera de hacer algo, todo depende de la aplicación en particular.

Ejemplo para su caso: suponga que tiene una clase que representa una estructura de configuración simple con 10 campos, pero sin funcionalidad real, por lo que no hay métodos, excepto un constructor. Todos los miembros pueden ser leídos / escritos. Personalmente preferiría

class MyConfig
{
public:
  int a;
  int b;
  int c;
  int d;
  int e;
};

mucho, mucho más que el siguiente, que tampoco agrega ninguna funcionalidad adicional sobre el original ..

class MyConfig
{
public:
  int GetA() const{ return a; }
  void SetA( int i ){ a = i; }
  int GetB() const{ return b; }
  void SetB( int i ){ b = i; }
//you get the point.. 
private:
  int a;
  int b;
  int c;
  int d;
  int e;
};
    
respondido por el stijn 13.03.2011 - 09:54
27

En general, sí, yo y muchos otros hacemos excepciones para los DTO, veamos este breve blogpost por tío Bob Martin.

Si todo lo que estás haciendo es crear variables privadas y usar captadores y definidores, deberías pensar por qué estás haciendo esto. Hay muchas personas que dicen que los captadores y los instaladores son malos, consulte este artículo o este artículo por Alan Holub. De ese artículo:

  

Resumiendo

     

Juntemos todo: Tú   no debe usar métodos de acceso   (getters y setters) a menos que   absolutamente necesario porque estos   Los métodos exponen información sobre cómo una   clase se implementa y como   Consecuentemente, haga su código más difícil   mantener. A veces métodos get / set   son inevitables, pero un OO experimentado   diseñador probablemente podría eliminar 99   Porcentaje de los accesores actualmente en   Su código sin mucha dificultad.

     

Los métodos de getter / setter a menudo hacen su   camino en el código porque el codificador era   pensar procedimentalmente. La mejor manera de   salir de esa mentalidad procesal   es pensar en términos de una conversación   entre objetos que tienen bien definidos   responsabilidades. CRC de Cunningham   El enfoque de la tarjeta es una gran manera de conseguir   comenzado.

    
respondido por el KeesDijk 13.03.2011 - 09:51
9

Hay una muy buena razón para usar getters y setters en Java en lugar de tener campos públicos.

El motivo es porque siempre debe codificar a interfaces , y las interfaces no permiten especificar campos sino solo métodos.

    
respondido por el user1249 13.03.2011 - 10:49
3

Java, a diferencia de otros lenguajes como Ruby, diferencia entre acceso directo a una propiedad y acceso a una propiedad a través de accesores / mutadores. Una buena práctica orientada a objetos dice que, siempre que sea posible, debe ocultar el estado interno de un objeto desde el exterior. Es decir, la representación interna de los datos no debe ser manipulada directamente por objetos externos. La razón es que podría aplicar algo de lógica al valor antes de que se ejecute la acción (es decir, validarlo, limpiar una cadena, formatear el retorno, ...). El problema es que la mayoría de la gente piensa que los "POJO" deben ser "lo más limpios posible", y terminan implementando estas validaciones / formaciones / limpieza en otros lugares, lo que deja al POJO tonto y tedioso para escribir.

Dicho esto, hace poco me encontré con una biblioteca llamada "lombok", que me permite escribir solo las propiedades y generará los captadores / setters sobre la marcha. Si necesito hacer algo de lógica adicional en cualquier accesor / mutador, solo hago la implementación real y lombok ignorará ese método específico.

    
respondido por el jpkrohling 13.03.2011 - 11:20
3

Como usted mismo lo pone:

  

Pero aquí está el problema: es un trabajo tedioso. [énfasis mío] Tiendo a perder rápidamente   interés en un proyecto cada vez que necesito tener una variable en una clase   que simplemente podría haber sido declarado público en lugar de privado con una   getter y un setter.

Usted está sorteando el trabajo tedioso al tratar de argumentar que es necesario dejar de existir, en lugar de hacerlo menos tedioso, lo que básicamente significa solucionar el problema en lugar de resolverlo. Para resolverlo:

Utilice las herramientas adecuadas y utilícelas correctamente

Si crear accesos simples es demasiado trabajo, entonces su conjunto de herramientas actual necesita mejoras.
De hecho, en cualquier momento en que haya un trabajo tedioso, su conjunto de herramientas necesita mejoras .

Para muchos idiomas, hay algún tipo de azúcar sintáctica disponible para crear accesores o puede usar preprocesadores para eso y la mayoría de los IDE proporcionan fragmentos de código / generadores de código. De hecho, en cualquier IDE decente, se trata de pulsar una tecla para convertir un campo público en uno privado con accesores.

Podría proporcionar una explicación bastante extensa sobre por qué el uso de campos públicos viola completamente la POO. Al mismo tiempo, la POO no es la verdad fundamental y, a veces, es mejor elegir conscientemente una alternativa, si sabes lo que estás haciendo y las circunstancias son las correctas. Entonces, sí, hay casos en los que el uso de campos públicos simples está bien.
Sin embargo, este no es el caso, ya que no está tomando esta decisión basándose en ningún tipo de restricciones técnicas, sino solo porque su flujo de trabajo necesita optimización.

    
respondido por el back2dos 08.02.2012 - 16:40
1

La exposición de miembros, ya sea como campos públicos o mediante simples captadores y definidores, va en contra de ideas originales de OO .

Si está modelando valores y no objetos, puede haber motivos para modelarlos como valores.

En términos puristas, los objetos se refieren al comportamiento, cualquier variable miembro es un detalle de implementación y ningún valor es parte del comportamiento. Entonces, si desea hacer OO purista cada vez que quiera crear un setter o un getter, debe hacerse preguntas sobre su diseño, ya que la necesidad de los getters y setters (cuando no se habla de valores como opuestos a los objetos) es un olor. que no está modelando lo que hace el sistema (comportamiento) sino lo que es (datos). Un paradigma que se centra en la separación de estos conceptos es DCI

    
respondido por el Rune FS 08.02.2012 - 15:07
0

Siempre es una palabra muy fuerte, y la evitaría. Si solo es cuestión de escribir para eso están las macros del teclado. Escriba un pequeño script que tome un código fuente de java y encuentre todas las vars públicas, conviértalas en privado y escriba las funciones de obtención y configuración para usted.

Me parece que siempre es una buena idea automatizar las partes de perforación y placa de caldera del trabajo. Mejora la calidad del código porque la computadora hace lo aburrido.

Solo recuerda lo siguiente:

  1. El código fuente es solo datos

  2. Los programas manipulan datos

  3. ¡Escriba un programa para manipular sus datos de manera útil!

¡Buena suerte!

    
respondido por el Zachary K 13.03.2011 - 10:59
0

El punto con captadores / definidores vs. variables públicas es la separación de preocupaciones. Las variables internas son un detalle de implementación de una clase y, por lo tanto, no deben verse desde fuera.

Lo que debería ser visible desde el exterior son las propiedades que maneja la clase, y estas propiedades pueden no tener una coincidencia de uno a uno con las variables internas.

Por ejemplo, una clase puede manejar una propiedad de 'temperatura'. Una variable interna puede estar vinculada a esta temperatura, pero los usuarios no deben suponer qué representa el valor almacenado en esa variable: ° C, ° F, ° K o incluso, según el sensor, la medida bruta expresada en: mm, V ...

Los captadores y definidores deben aplicar a las propiedades, no a las variables internas, permitiendo así que se incluyan las funciones de calibración o conversión.

De esa manera, los elementos internos de la clase pueden cambiar sin actualizar su interfaz y todos los demás componentes dependiendo de esa clase.

    
respondido por el mouviciel 08.02.2012 - 15:05
0

Después de leer algunas respuestas, mi primer punto sería que, en este contexto, no creo que debería es lo mismo que decir debe que no es lo mismo que decir Tengo que , creo que quizás estás enfatizando siempre .

  • debería implica que este es un consenso generalizado de que este es un enfoque mejor o más apropiado
    • usted debería siempre declarar a sus miembros como privados
  • must implica que esta es la forma en que se realiza
    • usted debe declarar en privado a sus miembros
  • tener que implica ninguna otra opción
    • usted tiene que declarar en privado a sus miembros

De hecho, en los tres ejemplos (particularmente dada la circunstancia de la cual derivó esta pregunta) uno lo haría y IMO debería (aunque no debe ni debe) consultar ninguna declaración que se les presente, así es como programa la mejor computadora de todas. Por ejemplo, si alguien dijera que siempre debe hacer algo a pesar de que sabe que esta vez sería perjudicial, ¿lo haría sin cuestionar su racional?

Me imagino que en este caso su tutor (probablemente por su facilidad) lo ha considerado, una mejor práctica con la que, de hecho, yo (y quizás muchos otros) estarían de acuerdo. La pregunta que siento nunca debería ser por qué hacer que un miembro sea privado, sino en realidad lo contrario a cómo hacerlo público, tomando como ejemplo a Facebook, a las personas claramente les gusta publicar información sobre ellos mismos, pero incluso entonces, tal vez solo mis amigos puedan ver esto. , mi familia puede ver eso, y usted, que no conozco, no puede ver nada.

Devolviendo esto a OOP y en particular a Java, una de las razones principales para los que obtienen y configuran es IMO (y puede que esté equivocado) un caso de buena práctica semántica, obj.getState() y obj.setState() en lugar de obj.state y obj.state = 'foo' , en ambos casos, sostendría que el proceso de hacerlo es imperativo. Me gustaría pensar que la orientación a objetos no solo consiste en romper con este paradigma, sino en encapsular datos y funciones en un componente reutilizable. Si no ocultamos nada, ¿acabamos con un espacio de nombres para almacenar datos y métodos?

Otro punto clave que creo que se reduce a anular, las clases que heredan de una súper clase que contiene variables públicas ahora están atascadas con una variable pública que a mi me parece que esto podría llevar a una disminución en la reutilización. Al utilizar captadores y definidores, ha proporcionado una forma para que las subclases anulen el acceso a sus variables, tal vez agregue un poco de validación con la que nunca se haya molestado.

En cuanto a ser tedioso en cuanto a los creadores y creadores de la escritura, esto es realmente nulo y sin valor ya que creo que la mayoría de los IDE harán mucho por ti (y como acabo de encontrar lombok, que se ve bastante bien y me recuerda a @property etc en objetivo-c)

En resumen, sí, debería utilizar siempre miembros privados a menos que tenga una buena razón para no hacerlo (los DTO serían, en cierta medida, una excepción razonable)

    
respondido por el T I 08.02.2012 - 17:06
-2

La razón por la que siempre tienes que implementar captadores y definidores es porque todos te dicen que lo hagas (personas sanas lo llaman Dogma). En los 10 años en que programo Java, probablemente el 99 por ciento de las propiedades que utilicé estén disponibles públicamente a través de captadores y configuradores, por lo que en la práctica SON públicos. Facilitamos la excepción, en lugar de la regla.

    
respondido por el Pierre 08.02.2012 - 14:35

Lea otras preguntas en las etiquetas