Java- Mejor práctica para getters, getter único o múltiple para diferentes variables?

Soy relativamente nuevo en la programación de Android (~ 2 Meses) ¿Es necesario tener getters para docenas de variables diferentes?

Por ejemplo –

//Yes I realise that this isn't 'dozens' public float getX() { return position.x; } public float getY() { return position.y; } public float getWidth() { return width; } public float getHeight() { return height; } public float getRotation() { return rotation; } 

Si bien sería necesario tener diferentes getters y setters para flotadores y cadenas, por ejemplo, ¿es mala práctica, y si es así por qué es, utilizar algo así como una instrucción switch para devolver variables diferentes?

 public float returnSomething(String theThing) { switch (theThing) { case "height": return height; case "rotation" : return rotation; case "width": return width; default: return 0; } } 

Entonces, ¿se considera malo el código anterior? Si es así, explique por qué.

Gracias por cualquier ayuda, esto no es realmente un problema ya que cualquiera de las dos formas funciona bien, simplemente no veo por qué la gente usaría decenas de getters y setters si no hay una buena razón.

Supongo que la misma pregunta se aplica a los setters

Porque el momento en que haces algo como

 public float returnSomething(String theThing) { switch (theThing) { case "height": return height; case "rotation" : return rotation; case "width": return width; default: return 0; } } 

Puedo sentir la siguiente pregunta para el desbordamiento de la pila, "¿Por qué mi altura siempre es de 0?"

Y luego código postal como

 public class GameThingy { //... private void doStuff(GameObject gameObject) { float gravity = 5*gameObject.returnSomething("hieght"); gameObject.setSomething("velocyty", gravity+50); } } 

Técnicamente, el momento en que haces un error tipográfico en cualquier lugar, tendrás problemas para encontrar la fuente del problema. Eso, y tienes suerte de que los campos están float , no tienen que ser.

Edit: Por cierto, este es realmente un problema típico en la definición del campo de interés en algunas consultas de base de datos. Como en, tener que especificar el campo que está buscando por una String .

Un ejemplo de la vida real es RealmQuery<T> .

Un RealmQuery<T> ve así:

 RealmQuery<User> query = realm.where(User.class); // Add query conditions: query.equalTo("name", "John"); // Execute the query: RealmResults<User> result1 = query.findAll(); 

Donde asumen que el User la clase es algo como esto:

 public class User { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 

Una nota interesante es que Realm crea una "subclase proxy" en la que redefinen los métodos setName y getName (¡también necesita getters / setters para hacer que algunos sistemas funcionen!

Pero lo que es importante aquí es que usted necesita para proporcionar el nombre del campo con "name" .

Más tarde, cualquier persona puede hacer un error tipográfico , o simplemente no recordar los campos de la parte superior de la cabeza. En este caso particular, tienden a crear un metamodelo (algo que almacena el nombre de los campos para usted) con el propósito de que no tendrá que usar las cadenas para referirse a los nombres de los campos.

Por ejemplo, en Criteria API, en lugar de

 Root<Pet> pet = cq.from(Pet.class); cq.select(pet.get("name")); 

Tienen el metamodelo como este:

 Root<Pet> pet = cq.from(Pet.class); cq.select(pet.get(Pet_.name)); 

Por lo tanto, elimina la necesidad de String s.

Y de manera similar, lo que tiende a hacer con Realm es crear un "metamodelo" (aunque ahora se puede generar para usted automáticamente con RealmFieldNamesHelper ):

 public class User extends RealmObject { @PrimaryKey private long id; private String name; public static enum Fields { //this is the "metamodel" ID("id"), NAME("name"); private String fieldName; Fields(String fieldName) { this.fieldName = fieldName; } public String getField() { return fieldName; } @Override public String toString() { return getField(); } } } 

Y así usted puede reemplazar la consulta así

 RealmResults<User> result2 = realm.where(User.class) .equalTo(User.Fields.NAME.getField(), "John") .or() .equalTo(User.Fields.NAME.getField(), "Peter") .findAll(); 

Pero con getters y setters, ya tienes el tipo de seguridad, y ya tienes los métodos que no tienes que recordar en la parte superior de tu cabeza – y así, tienes las comprobaciones de error de tiempo de compilación.

Así que para responder a su pregunta, la razón por la que es una mala práctica para referirse a las variables por nombre de cadena en Java es porque

1.) Los errores tipográficos pueden ocurrir, y el error se produce sólo en tiempo de ejecución , no en tiempo de compilación

2.) no es de tipo seguro ; Tienes la suerte de que consigas volver a float s, no importa lo que en este ejemplo, pero en el momento en que puede ser una String , es necesario devolver el Object y echarlo o utilizar public <T> T get(String field) { ... } Y quienquiera que llame el método debe saber exactamente lo que está recibiendo – también runtime-error propenso.

Getters & Setters le dan seguridad de tipo. Sin embargo, úselo sólo para variables que necesite acceder (obtener / establecer) desde fuera de la clase. Usted puede y debe minimizarlo usando constructores adecuados, que para la mayoría de los casos es el camino correcto porque aumenta la claridad del código al eliminar los cambios mágicos en el fondo, lo que puede ser un grave dolor para el código de múltiples hilos, pero puede ser Un gran problema incluso en el código regular con mala programación.

El hecho de tener veinte clases privadas de nivel de clase no significa que usted tiene que crear getXXX () y setXXX () para cada uno!

BTW: La mayoría de IDE de estos días como Eclipse puede generar automáticamente para usted.

Simplemente cree getters y setters cuando los necesite.

 public float returnSomething(String theThing) { switch (theThing) { case "height": return height; case "rotation" : return rotation; case "width": return width; default: return 0; } } 

Si intentas hacer area = returnSomething("width") * returnSomething("heigth") siempre se terminará con 0 área. Por qué, note el error de ortografía. Si tiene métodos separados, el compilador lo dirá en tiempo de compilación.

Además, tiene que hacer un montón de cheques si tiene muchas variables.

Yo no soy amigo de getters / setters, pero son probablemente la mejor solución aquí. El IDE proporcionará la generación de código para dichos campos.

Razón: roca sólida, no error propenso, más fácil para cambios posteriores.

Hacer sólo getters / setters cuando son realmente necesarios. Un public void move(float, float) y otros métodos más interesantes pueden colocar el cálculo de coordenadas en gran medida dentro de la propia clase.

Sólo necesita declarar getters y setters para las variables que necesitará usar o actualizar.

Creo que es sólo un hábito, su retorno. Algo funcionará bien, pero es más fácil llamar y entender:

 class.getHeight() 

que

 class.returnSomething("height") 

Tema interesante. Creo que hay una tercera respuesta. Existe un argumento que dice que Getters y Setters son malvados , y debe evitar usarlos en absoluto. Debido a que esencialmente declaran miembros como private pero conceden acceso de modificación pública a través de getters y setters.

Comparemos los dos. Aquí hay una clase de persona usando getters y setters

 public class Person { private String name; private int age; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int name) { this.age = age; } } 

Usando esta clase:

 Person me = new Person(); me.setName("Ian"); me.setAge(24); System.out.println("Name: " + me.getName()); System.out.println("Age: " + me.getAge()); 

Ahora creemos la misma clase sin usar getters y setters.

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

Y el acceso será:

 Person me = new Person(); me.name = "Ian"; me.age = 24; System.out.println("Name: " + me.name); System.out.println("Age: " + me.age); 

Como se puede ver el patrón getter y setter añade un poco de extra de mecanografía. Sin embargo, hay muchas ventajas de usar getters y setters.

Todo el argumento en contra del uso de getters y setters en un lenguaje orientado a objetos puede resumirse como:

El código de procedimiento recibe información y luego toma decisiones. El código orientado a objetos le dice a los objetos que hagan cosas. – Alec Sharp

Como un ejemplo simple, digamos que queremos escribir la información de una Person en la base de datos. Lo que algunos desarrolladores tienden a hacer es crear una interfaz de base de datos que tiene una función

 void writeToPersons(Person person) 

Que usará getters y setters para escribir los datos requeridos en la base de datos.

De acuerdo con el getter y setter nay sayers, Person sí debe ser responsable de escribir por sí mismo la base de datos.

 public class Person implements Storable { public void writeToDatabase() { } } 

Para responder a su pregunta, prefiero utilizar getters y setters que su segunda sugerencia, porque finalmente agregará un conjunto de constantes o enums para cada propiedad. Esto requiere el mantenimiento del código en dos lugares diferentes, que simplemente agrega otro punto de falla.

Estoy de acuerdo con las respuestas anteriores, pero voy a generalizar un poco. El problema con el método returnSomething es que cambia algunas comprobaciones ortográficas desde tiempo de compilación hasta tiempo de ejecución.

Hay tiempos y lugares para código muy flexible en el que la mayoría de los controles se realizan en tiempo de ejecución. En esas situaciones, no uso Java.

Las grandes ventajas de compilar comprobaciones de tiempo, ya los idiomas que las soportan, es que hacen el equivalente a pruebas universalmente cuantificadas: "Para cada programa compilable que no utiliza la reflexión, cada solicitud get es para un atributo válido". En lugar de "Para todos los casos de prueba en este conjunto de pruebas, cada solicitud de obtener es para un atributo válido".

  • ¿Cómo puedo descifrar la URL en la aplicación Android
  • Java montón espacio
  • Android Geofencing con Google Play Services 6.5.87
  • Android - Syncano SDK no funciona
  • Trabajo de newSingleThreadScheduledExecutor, si el hilo ya está ocupado
  • Cómo rellenar una base de datos SQLite con datos de un archivo xml?
  • Cómo almacenar elementos seleccionados de un ExpandableListView en un ArrayList
  • Volver a escribir el código Java a JS - la creación de un audio de bytes?
  • la importación com.badlogic.gdx.graphics.gl10 no se puede resolver
  • Pasando de la programación de Java a Android Application Developement
  • Cambiar el color de Switch en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.