setters getters español and java oop setter getter accessor

java - getters - ¿Son malos los que consiguen y los que establecen son malos diseños? Consejos contradictorios vistos



getter y setter java netbeans (16)

Esta pregunta ya tiene una respuesta aquí:

Actualmente estoy trabajando en un juego simple en Java con varios modos diferentes. He extendido una clase de juego principal para poner la lógica principal dentro de las otras clases. A pesar de esto, la clase de juego principal sigue siendo bastante fuerte.

Después de echar un vistazo rápido a mi código, la mayoría era Getters y Setters (60%) en comparación con el resto que realmente se necesita para la lógica del juego.

Un par de búsquedas en Google han afirmado que los Getters y Setters son malos, mientras que otros han afirmado que son necesarios para una buena práctica de OO y programas excelentes.

¿Entonces qué debo hacer? ¿Cuál debería ser? ¿Debería estar cambiando a mis Getters y Setters para mis variables privadas, o debo seguirlas?


Como siempre la única respuesta es: depende. Si usted es el único peron que toca el código, puede hacer cualquier cosa con la que se sienta cómodo, incluso tomar atajos.

Una de las ventajas de utilizar los configuradores es que las comprobaciones solo deben realizarse en una ubicación de su código.

Es posible que desee prestar más atención a lo que realmente se obtiene y establece con estos métodos. Si los está utilizando para proporcionar acceso a valores constantes, probablemente se encuentre mejor utilizando constantes.


Ellos son absolutamente malos.

Lamentablemente, @coobird no "aplican el concepto de encapsulación", todo lo que hacen es hacerle creer que está encapsulando datos cuando, de hecho, está exponiendo datos a través de una propiedad con delirios de grandeza de método. Cualquier cosa que un captador / configurador hace un campo público hace mejor.

Primero, si desea datos públicos, hágalo público, deshágase de los métodos de obtención y configuración para reducir la cantidad de métodos que el cliente tiene que analizar y hacerlo cognitivamente más sencillo para que el cliente cambie su valor mediante, por ejemplo.

object.field = value;

en lugar de la más cognitivamente intensa

object.setField(value);

donde el cliente ahora debe verificar el método getter / setter para ver si tiene algún efecto secundario.

En segundo lugar, si realmente necesita hacer algo más en el método, ¿por qué llamarlo método get / set cuando tiene más responsabilidades que simplemente obtener o configurar? Sigue el SRP o llama al método algo que realmente te diga qué hace el método completo , como los ejemplos de Zarkonnen que mencionó, por ejemplo.

public void kill(){ isAlive = false; removeFromWorld(this); }

en lugar de

public void setAlive(boolean isAlive){ this.isAlive = isAlive; if (isAlive) addToWorld(this); else removeFromWorld(this); }

¿Dónde dice el método setAlive (booleano) al cliente que, como efecto secundario, eliminará el objeto del mundo? ¿Por qué el cliente debe tener algún conocimiento sobre el campo isAlive? Además, ¿qué sucede cuando el objeto se vuelve a agregar al mundo, debería reinicializarse? ¿Por qué el cliente se preocupa por algo de eso?

En mi humilde opinión, la moraleja es nombrar métodos para decir exactamente lo que hacen, seguir el SRP y deshacerse de los captadores / setters. Si hay problemas sin los captadores / setters, diga a los objetos que hagan su propio trabajo sucio dentro de su propia clase en lugar de tratar de hacer cosas con ellos en otras clases.

Aquí termina mi perorata, perdón por eso;)


Es posible que desee reemplazar algunas de sus clases por clases de valor. Esto te permitirá eliminar el getter y evitar problemas cuando el contenido se modifique debajo de ti.


Es una pendiente resbaladiza.

Un simple objeto de transferencia (u objeto de parámetro) puede tener el único propósito de mantener algunos campos y proporcionar sus valores a pedido. Sin embargo, incluso en ese caso degenerado se podría argumentar que el objeto debería ser inmutable, configurado en el constructor y exponiendo solo los métodos get ...

También está el caso de una clase que expone algunos "mandos de control"; La interfaz de usuario de la radio de su automóvil probablemente se puede entender como exponer algo como getVolume , setVolume , getChannel y setChannel , pero su funcionalidad real es recibir señales y emitir sonido. Pero esos mandos no exponen muchos detalles de implementación; no se sabe por esas características de la interfaz si la radio es transistores, en su mayoría software o tubos de vacío.

Cuanto más empiece a pensar en un objeto como un participante activo en una tarea de dominio de problemas, más pensará en términos de pedirle que haga algo en lugar de pedirle que le informe sobre su estado interno, o pedirle que lo haga. Sus datos para que otro código pueda hacer algo con esos valores.

Tan malvado"? Realmente no. Pero cada vez que te inclinas a poner un valor y exponer ambos métodos para get y set ... ese valor, pregúntate por qué, y cuál es realmente la responsabilidad del objeto. Si la única respuesta que puedes darte a ti mismo es "mantener este valor para mí", entonces quizás esté ocurriendo algo además de OO aquí.


Esto depende del lenguaje de programación en cuestión. Su pregunta está enmarcada en el contexto de Java, donde parece que los captadores y los definidores generalmente son considerados como algo bueno.

En contraste, en el mundo de Python, generalmente se los considera de estilo malo: agregan líneas al código sin agregar funcionalidad. Cuando los programadores de Python lo necesitan, pueden usar la metaprogramación para detectar la obtención y / o configuración de atributos de objetos.

En Java (al menos la versión de Java que aprendí hace una década), eso no fue posible. Por lo tanto, en Java, por lo general, es mejor utilizar religiosamente a los captadores y definidores, de modo que si lo necesita, puede anular el acceso a las variables.

(Esto no hace que Python sea necesariamente mejor que Java, solo que diferente).


Getters y setters hacen cumplir el concepto de encapsulation en la programación orientada a objetos.

Al tener los estados del objeto ocultos del mundo exterior, el objeto está verdaderamente a cargo de sí mismo, y no puede ser alterado de una manera que no sea la intención. Las únicas formas en que se puede manipular el objeto son a través de métodos públicos expuestos, tales como captadores y definidores.

Hay algunas ventajas para tener getters y setters:

1. Permitir cambios futuros sin modificación al código que usa la clase modificada.

Una de las grandes ventajas de usar un getter y setter es que una vez que se definen los métodos públicos y llega un momento en que la implementación subyacente debe cambiarse (por ejemplo, encontrar un error que deba solucionarse, utilizando un algoritmo diferente para mejorar el rendimiento). , etc.), al hacer que los captadores y los definidores sean la única forma de manipular el objeto, permitirá que el código existente no se rompa y funcionará como se espera incluso después del cambio.

Por ejemplo, digamos que hay un método setValue que establece la variable privada de value en un objeto:

public void setValue(int value) { this.value = value; }

Pero entonces, hubo un nuevo requisito que necesitaba seguir la cantidad de veces value se cambió el value . Con el colocador en su lugar, el cambio es bastante trivial:

public void setValue(int value) { this.value = value; count++; }

Si el campo de value fuera público, no hay una manera fácil de regresar más tarde y agregar un contador que haga un seguimiento del número de veces que se cambió el valor. Por lo tanto, tener captadores y definidores es una forma de "preparar el futuro" de la clase para los cambios que se producirán más adelante.

2. Hacer cumplir los medios por los cuales el objeto puede ser manipulado.

Otra forma en que los captadores y definidores son útiles es imponer las formas en que se puede manipular el objeto, por lo tanto, el objeto tiene el control de su propio estado. Con las variables públicas de un objeto expuesto, se puede corromper fácilmente.

Por ejemplo, un objeto myArray contiene una matriz int llamada myArray . Si la matriz fuera un campo público, simplemente no será inmutable:

ImmutableArray a = new ImmutableArray(); int[] b = a.myArray; b[0] = 10; // Oops, the ImmutableArray a''s contents have been changed.

Para implementar una matriz realmente inmutable, se debe escribir un getter para la matriz (método getArray ) para que devuelva una copia de su matriz:

public int[] getArray() { return myArray.clone(); }

E incluso si ocurre lo siguiente:

ImmutableArray a = new ImmutableArray(); int[] b = a.getArray(); b[0] = 10; // No problem, only the copy of the array is affected.

El ImmutableArray es de hecho inmutable. Exponer las variables de un objeto permitirá que se manipulen de maneras que no están pensadas, pero que solo exponen ciertas maneras (captadores y definidores), el objeto puede manipularse de la manera prevista.

Supongo que tener captadores y definidores sería más importante para las clases que forman parte de una API que otros utilizarán, ya que permite mantener la API intacta y sin cambios, al tiempo que permite cambios en la implementación subyacente.

Con todas las ventajas de los captadores y definidores, si el captador simplemente devuelve el valor de la variable privada y el establecedor simplemente acepta un valor y lo asigna a una variable privada, parece que los captadores y el definidor son simplemente extraños y realmente un residuos. Si la clase va a ser solo para uso interno por una aplicación que no va a ser utilizada por otros, el uso extensivo de getters y setters puede no ser tan importante como al escribir una API pública.


He estado programando en java desde hace pocos meses, y he aprendido que deberíamos usar captadores y configuradores solo cuando sea necesario para la aplicación

que te diviertas :)


La presencia de captadores y colocadores tiende a indicar (un "olor" si te gusta ese tipo de lenguaje de la escuela primaria) que hay un problema de diseño. Los captadores y colocadores triviales son apenas distinguibles de los campos públicos. Normalmente, el código que opera en los datos estará en una clase diferente: pobre encapsulación, y lo que usted esperaría de los programadores no está cómodo con OO.

En algunos casos, los captadores y los setters están bien. Pero como norma, un tipo con captadores y definidores indica problemas de diseño. Los captadores trabajan para la inmutabilidad; los instaladores trabajan para "decir, no preguntar". Tanto la inmutabilidad como el "decir no preguntar" son buenas opciones de diseño, siempre que no se apliquen en un estilo superpuesto.


Mi opinión es que los captadores y setters son un requisito para los buenos programas. Quédate con ellos, pero no escribas getters / setters innecesarios, no siempre es necesario tratar directamente con todas las variables.


Realmente no creo que sean malvados. Pero me encantaría vivir en un mundo en el que nunca tuve que usarlos a menos que realmente lo necesitara.

Un ejemplo que leí anteriormente fue future-proofing su código. Por ejemplo:

public void setValue(int value) { this.value = value; }

Luego, los requisitos cambian y debe hacer un seguimiento de cuántas veces se estableció el valor.

Asi que:

public void setValue(int value) { this.value = value; count++; }

Esto es hermoso. Lo entiendo. Sin embargo, en Ruby, ¿lo siguiente no serviría para el mismo propósito?

someobject.my_value = 100

Más tarde, debe hacer un seguimiento del número de veces que se configuró my_value . Bueno, entonces, ¿no podrías simplemente anular el setter THEN y solo THEN ?

def my_value=(value) @my_value = value @count++ end

Estoy a favor de un código hermoso, pero debo admitirlo, mirar a través de las montañas de clases de Java que tenemos y ver literalmente miles y miles de líneas de código que no son NADA, pero que los métodos básicos de obtención y configuración son feos y molestos.

Cuando estuve desarrollando C # a tiempo completo, utilizamos propiedades públicas todo el tiempo e hicimos captadores / configuradores personalizados solo cuando fue necesario. Funcionó a la perfección y no rompió nada.


Si necesita acceso externo a valores individuales de campos, use getters y / o setters. Si no, no lo hagas. Nunca use campos públicos. ¡Es tan simple como eso! (Ok, nunca es tan simple, pero es una buena regla de oro).

En general, también debe encontrar que necesita suministrar un setter con menos frecuencia que un getter, especialmente si está tratando de hacer que sus objetos sean inmutables, lo cual es algo bueno (pero no siempre es la mejor opción), pero incluso si no.


Solo para su información: además de todas las excelentes respuestas en este hilo, recuerde que de todas las razones por las cuales puede proponer o no a los que las obtienen o las ponen, el rendimiento no es uno (como algunos podrían creer). La JVM es lo suficientemente inteligente como para incluir a los captadores / instaladores triviales en línea (incluso los no final , siempre que no estén realmente anulados).


También existe el punto de vista de que la mayoría de las veces, el uso de los configuradores aún rompe la encapsulación al permitirle establecer valores sin significado. Como un ejemplo muy obvio, si tiene un contador de puntajes en el juego que solo sube, en lugar de

// Game private int score; public void setScore(int score) { this.score = score; } public int getScore() { return score; } // Usage game.setScore(game.getScore() + ENEMY_DESTROYED_SCORE);

debería ser

// Game private int score; public int getScore() { return score; } public void addScore(int delta) { score += delta; } // Usage game.addScore(ENEMY_DESTROYED_SCORE);

Este es quizás un ejemplo un tanto fácil. Lo que estoy tratando de decir es que hablar de los buscadores / setters contra los campos públicos a menudo oculta problemas mayores con los objetos que manipulan el estado interno de los demás de una manera íntima y, por lo tanto, están demasiado unidos.

La idea es hacer métodos que hagan directamente las cosas que quieres hacer. Un ejemplo sería cómo establecer el estado "vivo" de los enemigos. Podría estar tentado a tener un método setAlive (boolean alive). En su lugar, debería tener:

private boolean alive = true; public boolean isAlive() { return alive; } public void kill() { alive = false; }

La razón de esto es que si cambia la implementación de que las cosas ya no tienen un valor booleano "vivo" sino un valor de "puntos de golpe", puede cambiarlo sin romper el contrato de los dos métodos que escribió anteriormente:

private int hp; // Set in constructor. public boolean isAlive() { return hp > 0; } // Same method signature. public void kill() { hp = 0; } // Same method signature. public void damage(int damage) { hp -= damage; }


Tu clase de Juego probablemente esté siguiendo el objeto de Dios antipatrón si expone tantas variables. No hay nada de malo en conseguir y establecer (aunque su verbosidad en Java puede ser un poco molesta); en una aplicación bien diseñada donde cada clase tiene una funcionalidad claramente separada, no necesitarás docenas de ellas en una sola clase.

Edición: si el punto principal para los captadores y configuradores es "configurar" la clasificación del juego (entiendo tu comentario de esa manera), entonces probablemente no necesites que los captadores (es perfectamente correcto que una clase acceda a sus propias variables privadas) sin usar los métodos de obtención), y probablemente pueda colapsar muchos de los configuradores en "configuradores de grupo" que establecen varias variables que pertenecen conceptualmente.


Ya has tenido muchas respuestas buenas sobre esto, así que solo daré mis dos centavos. Getters y setters son muy, muy malvados. Básicamente, te permiten fingir que ocultas las partes internas de tu objeto cuando la mayoría de las veces todo lo que has hecho es un código redundante que no hace nada para ocultar el estado interno. Para un POJO simple, no hay razón por la que getName () y setName () no puedan reemplazarse con obj.name = "Tom".

Si la llamada al método simplemente reemplaza la asignación, entonces todo lo que ganó al preferir la llamada al método es el código inflado. Desafortunadamente, el lenguaje ha consagrado el uso de captadores y definidores en la especificación de JavaBeans, por lo que los programadores de Java se ven obligados a usarlos, incluso cuando hacerlo no tiene ningún sentido.

Afortunadamente, Eclipse (y probablemente también otros IDE) le permite generarlos automáticamente. Y para un proyecto divertido, una vez construí un generador de código para ellos en XSLT. Pero si hay algo de lo que me libraría en Java, es la dependencia excesiva de los captadores y definidores.


  • Muy malvado: los campos públicos.
  • Algo malvado: Hechiceros y setters donde no son requeridos.
  • Bien: los buscadores y los programadores solo cuando son realmente necesarios, hacen que el tipo exponga el comportamiento "más grande" que utiliza su estado, en lugar de simplemente tratar el tipo como un repositorio de estado para ser manipulado por otros tipos.

Sin embargo, realmente depende de la situación; a veces, en realidad solo desea un objeto de datos sin sentido.