Convenciones de Java: use getters / setters DENTRO de la clase?

Mi profesor realmente enfatiza la protección contra filtraciones de privacidad al usar siempre accesos y mutadores para acceder a variables de instancia privadas; sin embargo, ¿tengo que usar los getters / setters de una clase dentro de la clase?

Entonces, por ejemplo, si tengo la siguiente clase:

public class Person { private String name; private int age; } 

y quiero escribir un método toString () para ello. ¿Puedo escribir solo?

 public String toString() { return name + " " + age; } 

O ¿tengo que hacer algo como esto?

 public String toString() { return this.getName() + " " + this.getAge(); } 

PUEDES hacer cualquiera de los dos. Sin embargo, su profesor puede apreciar el uso de los métodos en lugar del acceso directo. Este es el por qué.

Digamos que tienes una clase como esta:

 class SomeClass { private int someValue; private String someString; public SomeClass(int someValue, String someString) { this.someValue = someValue; this.someString = someString; } public int someValue() { return someValue; } public int someString() { return someString; } public String toString() { return someValue + ": " + someString; } } 

Es bastante sencillo, ¿verdad? Bueno, ¿y si de repente queremos CAMBIAR la implementación de cómo calculamos someValue y basarlo en someString ?

 public int someValue() { int value = 0; for(int i = 0; i < someString.length; i++) { if(someString.charAt(i) == ' ') value++; } return value; } 

Ahora también debe cambiar cada lugar donde se usó la variable someValue .

Entonces, si desea hacer que el código sea más fácil de mantener a largo plazo, use las llamadas a métodos. De esta forma, cuando codifica los cambios en usted (y créame, esto cambia todo el tiempo) solo tiene que cambiarlo en un lugar en lugar de dos.

Y sí, querrías usar una llamada a método para obtener someString lugar del acceso directo en el último método 🙂

Cuando diseño una clase trato de hacer una distinción clara entre el interior (detalles de implementación) y el exterior (la interfaz expuesta al mundo). Getters y setters proporcionan un lugar conveniente para convertir valores entre la forma en que se almacenan en los miembros de la instancia del objeto y la forma en que los ve el mundo exterior. Usar getters y setters internamente sería estúpido, porque se estarían acostumbrando tanto por dentro como por fuera.

Si desea ocultar parte de una clase de otra parte de la misma clase, considere dividir la parte que desea ocultar en su propia clase.

Por lo general, no es una buena idea por varias razones:

  • Es posible que ni siquiera desee accesodores para todos los campos
  • Algunos usuarios pueden hacer una copia defensiva para no exponer el estado interno, esto normalmente no es necesario dentro de la clase en la que sabes que no vas a modificarlo, o simplemente incorrecto si sabes que vas a modificarlo.
  • Hace que la depuración sea más molesta, porque tienes que seguir los getters / setters
  • Hace que leer el código sea más difícil en la mayoría de los IDE, ya que la mayoría de ellos colorean los campos de forma diferente a las variables locales

… pero como siempre, hay excepciones. Algunos setters pueden tener efectos colaterales (por ejemplo, establecer un segundo valor) que QUIERES ejecutar, entonces podría ser mejor usar el setter. Además, si diseña su clase para la herencia, puede ser mejor ir a través de un descriptor de acceso si desea que la subclase pueda alterar el comportamiento.

En general, no. Si su getter devuelve algo que no sea el valor del campo, entonces debe usar el método, pero en ese caso raro su método debería tener un nombre más descriptivo. Por un mal ejemplo, si tienes:

 public void setName(String name) { _name = name; } 

y tu getter devolvió algo más, como

 public String getName() { return _name.toUpperCase(); } 

entonces sí, debes usar el getter. Sin embargo, sería mejor tener un nombre más descriptivo para ese getter:

 public String getNameAsUppercase() { return _name.toUpperCase(); } 

No, tu no. Puede acceder a cualquier variable, privada, pública o protegida, desde dentro de la clase.

Aquí hay algunas tablas para ayudarlo:

enter image description here

Fuente: Tutoriales de Java

Puede usar los accessors y mutators, pero es un estándar desordenado a seguir.

Atormenta tu código y confunde a cualquiera que intente leerlo pensando que podría no ser parte de tu clase.

Básicamente, solo acceda a las variables directamente desde dentro de su clase, e indirectamente desde cualquier otro lugar.

Por otro lado, considérelo desde el punto de vista del diseño. Una de las motivaciones para getters / setters es que el almacenamiento de datos subyacente puede cambiar y las cosas que implementan la clase no necesitarán cambiarse ya que está encapsulado.

Entonces, teniendo esto en cuenta, el uso de getters / setters dentro de la clase facilita los cambios futuros. En lugar de tener que encontrar todos los lugares que alteran al miembro directamente, solo tiene que cambiar el getter / setter. Dependiendo de la complejidad de la clase, esto puede reducir significativamente la cantidad de trabajo que se necesita para cambiar los miembros de almacenamiento.

Por ejemplo, supongamos que comienzas con la variable de edad en años. Luego decides más tarde almacenarlo como segundos por algún motivo. Pero de todos modos, siempre quieres imprimirlo en años. Entonces en su ejemplo, podría hacer los cálculos en su función toString () (y en cualquier otro lugar que desee años como unidades) o puede simplemente cambiar los cálculos en la rutina getAge () para devolver años de los segundos y nada más tiene cambiar.

Obviamente ese ejemplo es un poco trivial. Cuanto más complicada es la clase, más útil es usar getters / setters dentro de ella.

Si su clase (o los métodos de acceso en cuestión) no es final , entonces definitivamente debe usar los métodos de acceso.

Si otra clase extiende la suya y anula esos accesadores, su clase debe usar los accesadores reemplazados. Si esto rompería su superclase, entonces su superclase está diseñada incorrectamente; evite que los accesores sean anulados con final , o cambie el diseño de su clase.

No, puede usar directamente las variables de su instancia dentro de la clase, no está violando ninguna “regla”. Los getters y setters son obligatorios para que otras clases accedan a variables de instancia de una clase para no violar el principio de encapsulación (que es bastante importante en la progtwigción de OO).

Al final es una cuestión de elección, pero está guardando una llamada de método usando su primer ejemplo.

Creo que deberíamos usar getters () y setters () en lugar de acceder directamente. también hace que la depuración sea muy fácil. por ejemplo, si necesita asignar un lugar con varias variables en su clase y luego quiere encontrar desde cuántos lugares se le asigna la variable, entonces necesita encontrar toda la asignación y establecer el punto de ruptura.

pero si usas un setter puedes simplemente poner un punto de quiebre dentro del método setter y puedes ver la cantidad de tiempo que se le asigna la variable.

Si existe getters y setters, entonces debería usarse siempre incluso dentro de la clase. Por supuesto, si getter y setter hacen algo más en el método, entonces debe considerarse si cumple con las necesidades.

Debe usarse, no se deben usar medios. La propiedad se puede usar directamente (solo dentro de la clase si la propiedad es privada, y debería serlo), pero en buenas prácticas es usar getter y setter.

Por lo tanto, es posible usar la propiedad directamente, pero recomiendo usar get y set porque brinda más flexibilidad y puede hacer algo más que asignar u obtener de manera típica.

Por ejemplo, si en primer lugar, setter solo establece algo, pero después de un tiempo setter se cambia para hacer algo más.

  setName(name){ this.name=name; } 

Entonces en el código setName("John"); es igual name="John" . Pero imagina que después de un tiempo queremos establecer otra propiedad cuando se establece el name :

  setName(name){ this.name=name; this.nameIsSet=true; } 

otro ejemplo (patrón de escucha) :

 setName(name){ this.name=name; this.listener.nameChanged(this.name); //we call listener that variable changed } 

Entonces el progtwigdor necesita encontrar cada asignación como name="John" en la clase y refactorizarla a un nuevo comportamiento. Si solo se usa setName entonces no se debe hacer ningún cambio de código.

Por supuesto, todo depende de la necesidad y es posible que esa configuración, obtener propiedad del exterior haga algo más y diferente y no cumpla con nuestra necesidad dentro de la clase.