Buscar..


Introducción

Este artículo analiza los captadores y setters; La forma estándar de proporcionar acceso a los datos en las clases de Java.

Adición de Getters y Setters

La encapsulación es un concepto básico en la POO. Se trata de envolver los datos y el código como una sola unidad. En este caso, es una buena práctica declarar las variables como private y luego acceder a ellas a través de Getters y Setters para verlas y / o modificarlas.

public class Sample {
  private String  name;
  private int age;

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

No se puede acceder a estas variables privadas directamente desde fuera de la clase. Por lo tanto, están protegidos contra el acceso no autorizado. Pero si desea verlos o modificarlos, puede usar los Getters y Setters.

getXxx() método getXxx() devolverá el valor actual de la variable xxx , mientras que puede establecer el valor de la variable xxx utilizando setXxx() .

La convención de nomenclatura de los métodos es (en la variable de ejemplo se llama variableName ):

  • Todas las variables no boolean

     getVariableName()   //Getter, The variable name should start with uppercase
     setVariableName(..) //Setter, The variable name should start with uppercase
    
  • variables boolean

      isVariableName()     //Getter, The variable name should start with uppercase
      setVariableName(...) //Setter, The variable name should start with uppercase
    

Los captadores y definidores públicos forman parte de la definición de propiedad de un Java Bean.

Usar un setter o getter para implementar una restricción

Setters y Getters permiten que un objeto contenga variables privadas a las que se puede acceder y cambiar con restricciones. Por ejemplo,

public class Person {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(name!=null && name.length()>2)
           this.name = name;
    }
}

En esta clase de Person , hay una sola variable: name . Se puede acceder a esta variable usando el método getName() y cambiarla usando el setName(String) , sin embargo, establecer un nombre requiere que el nuevo nombre tenga una longitud mayor que 2 caracteres y no sea nulo. El uso de un método de establecimiento en lugar de hacer público el name la variable permite a otros establecer el valor del name con ciertas restricciones. Lo mismo se puede aplicar al método getter:

public String getName(){
   if(name.length()>16)
      return "Name is too large!";
   else
      return name;
}

En el método getName() modificado anterior, el name se devuelve solo si su longitud es menor o igual a 16. De lo contrario, se devuelve "Name is too large" . Esto permite al programador crear variables que son alcanzables y modificables como lo deseen, evitando que las clases de clientes editen las variables de forma no deseada.

¿Por qué usar Getters y Setters?

Considere una clase básica que contiene un objeto con captadores y definidores en Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

No podemos acceder a la variable de count porque es privada. Pero podemos acceder a los getCount() y setCount(int) porque son públicos. Para algunos, esto podría plantear la cuestión; ¿Por qué introducir el intermediario? ¿Por qué no simplemente hacer que cuenten público?

public class CountHolder {
  public int count = 0;
}

Para todos los efectos, estos dos son exactamente iguales, en cuanto a funcionalidad. La diferencia entre ellos es la extensibilidad. Considera lo que dice cada clase:

  • Primero : "Tengo un método que le dará un valor int , y un método que establecerá ese valor en otro int ".
  • Segundo : "Tengo un int que puedes configurar y obtener como desees".

Estos pueden sonar similares, pero el primero es en realidad mucho más protegido en su naturaleza; solo te permite interactuar con su naturaleza interna según lo dicte. Esto deja el balón en su corte; Se llega a elegir cómo se producen las interacciones internas. El segundo ha expuesto su implementación interna externamente, y ahora no solo es propenso a usuarios externos, sino que, en el caso de una API, se compromete a mantener esa implementación (o, de lo contrario, a liberar una API no compatible con versiones anteriores).

Consideremos si queremos sincronizar el acceso para modificar y acceder al conteo. En el primero, esto es simple:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

pero en el segundo ejemplo, esto es ahora casi imposible sin pasar por y modificar cada lugar donde se hace referencia a la variable de count . Peor aún, si este es un elemento que está proporcionando en una biblioteca para que otros lo consuman, no tiene una forma de realizar esa modificación y se ve obligado a tomar la decisión difícil mencionada anteriormente.

Así que plantea la pregunta; ¿Son las variables públicas algo bueno (o, al menos, no malvado)?

No estoy seguro Por un lado, puede ver ejemplos de variables públicas que han pasado la prueba del tiempo (IE: la variable de out referenciada en System.out ). Por otro lado, proporcionar una variable pública no ofrece beneficios más allá de los gastos generales extremadamente mínimos y la posible reducción de la notoriedad. Mi pauta aquí sería que, si planea hacer pública una variable, debe juzgarla con estos criterios con un prejuicio extremo :

  1. La variable debe tener ninguna razón concebible cambiar nunca en su aplicación. Esto es algo que es extremadamente fácil de arruinar (y, aunque lo hagas bien, los requisitos pueden cambiar), por lo que el método común es el método común. Si va a tener una variable pública, esto realmente debe ser pensado, especialmente si se publica en una biblioteca / framework / API.
  2. La variable debe ser referenciada con la frecuencia suficiente para que las ganancias mínimas de reducir la verbosidad lo justifiquen. Ni siquiera creo que la sobrecarga para usar un método en lugar de una referencia directa deba considerarse aquí. Es demasiado insignificante para lo que estimaría de manera conservadora que es el 99.9% de las aplicaciones.

Probablemente hay más de lo que no he considerado de la cabeza. Si alguna vez tienes dudas, usa siempre getters / setters.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow