¿Por qué el método getter y setter es importante en Java?

Me han enseñado a usar siempre getters y setters. Sin embargo, no conozco los pros y los contras de estos métodos, ya que al implementarlos estamos exponiendo los datos y también ocultándolos.

Estoy un poco confundido acerca de esto. ¿Alguien puede dar un consejo adecuado sobre por qué usamos un getter / setter y cuáles son las ventajas?

El patrón básico de “campo privado con captador público y establecedor que no hace nada más que devolver o establecer el campo” es completamente inútil en lo que respecta a la encapsulación, excepto que le da la oportunidad de cambiarlo más tarde sin cambiar la API.

Entonces no uses ese patrón sin pensar. Considere cuidadosamente qué operaciones realmente necesita.

El verdadero objective de getters y setters es que solo debe usarlos donde sean apropiados, y que pueden hacer más que solo obtener y establecer campos.

  • Puedes tener solo un getter. Entonces la propiedad es de solo lectura. Este debería ser el caso más común.
  • Solo puede tener un colocador, lo que hace que la propiedad sea configurable, pero comunica que nada más debe depender de su valor
  • Un getter puede calcular un valor de varios campos en lugar de devolver un campo.
  • Un getter puede hacer una copia defensiva
  • Un getter puede realizar una operación de extracción costosa perezosamente y usar un campo para almacenar en caché el valor
  • Un colocador puede hacer verificaciones de cordura y lanzar IllegalArgumentException
  • Un colocador puede notificar a los oyentes de los cambios en el valor
  • Puede tener un setter que establezca múltiples campos juntos porque se corresponden conceptualmente. Esto no cumple con la especificación JavaBeans, por lo tanto, no lo haga si depende de frameworks o herramientas que esperan JavaBeans. De lo contrario, es una opción útil.

Todas estas cosas son detalles de implementación que están ocultos detrás de la interfaz simple de “getter and setter”. De eso se trata la encapsulación.

La idea de getters y setters es controlar el acceso a las variables en una clase. De esta forma, si el valor necesita cambiarse internamente para ser representado de una manera diferente, puede hacerlo sin romper ningún código fuera de la clase.

Por ejemplo, supongamos que tiene una clase con una variable de distancia, y se midió en pulgadas. Pasan unos meses, estás usando esta clase en muchos lugares y de repente te das cuenta de que necesitas representar ese valor en centímetros. Si no usaste un getter y un setter, tendrías que rastrear cada uso de la clase y convertir allí. Si usaste un getter y un setter, puedes simplemente cambiar esos métodos y todo lo que use la clase no se romperá.

 public class Measurement { /** * The distance in centimeters. */ private double distance; /** * Gets the distance in inches. * @return A distance value. */ public double getDistance() { return distance / 2.54; } /** * Sets the distance. * @param distance The distance, in inches. */ public void setDistance(double distance) { this.distance = distance * 2.54; } } 

Una buena ventaja que se tiene en cuenta es que puede crear un campo ReadOnly sin implementar un setter para ese campo en particular.

No hay nada de malo con el uso de getters y setters: solo tenga en cuenta que al usarlos y al hacerlos públicos, estará exponiendo sus variables y, de algún modo, violando la encapsulación. Esto es lo que el artículo que menciona está tratando de advertir: no solo genere automáticamente getters y setters para todas las variables de instancia privadas; piense en lo que quiere exponer a otras clases (y en qué nivel, es decir, privado / protegido / público) para que esté exponiendo solo cuando sea necesario.

Aquí está el inconveniente. Los Getters / Setters tienden a exponer los detalles de implementación de su clase al mundo exterior. Eso no es algo bueno. Imagine que está escribiendo un paquete de software de mecánica automotriz. Por lo tanto, necesitará una clase de automóvil, y por lo tanto expone los captadores y ajustadores de los campos

 Date lastOilChangeDate; int lastOilChangeMileage; 

en esta clase. Esto se debe a que el software desea enviar correos electrónicos cuando los automóviles de los clientes necesitan cambios de aceite.

Pero, ¿qué sucede cuando salen autos nuevos donde se determina si un automóvil necesita un cambio de aceite de manera diferente a ‘cada 3000 millas o 3 meses’? Quizás estos autos nuevos tienen un sensor en el cárter que midió la suciedad. Obviamente, querrías usar esto para determinar si se necesitaba un cambio de aceite.

El problema era que estabas resolviendo el problema incorrecto con esos getter / setters. Nadie quiere saber realmente cuándo fue el último cambio de aceite, quieren saber si necesita otro. Eran solo detalles de implementación, pero los hizo parte de la interfaz. Lo que deberías haber hecho fue agregar un método

 public boolean needsOilChange() 

y luego la clase Car podría implementar como quisiera. Si el algoritmo cambia, la clase Mechanic no debería hacerlo porque todo lo que necesitaba era el método needsOilChange.

esto se usa principalmente en beans Java como a continuación.

public Class MyBean{

private int var1;

public void setVar1(int pVar1){

this.var1=pvar1;

}

public int getVar1(){

return var1; `

}

}

los beneficios son los siguientes

1. con esto podemos lograr Encapsulación

2. se denomina patrón de diseño DTO (Objeto de transferencia de datos) . se usa para transferir datos de una capa a otra capa en aplicaciones basadas en MVC. como usted puede obtener datos ingresados ​​por el usuario desde el formulario (usando getters) y puede usar los mismos datos para insertarlos en la base de datos (mediante el uso de setter) y vice verca. últimos frameworks (SPring) que lo proporcionan como una funcionalidad incorporada.