2012-02-09 12 views
6

Puedo llamar variables de 2 maneras.Forma correcta de obtener variables de otra clase

Uno de ellos es sólo para hacerlo de esta manera:

MyClass myClass = new MyClass();  

myLocalVar = myClass.myVarVal; 

Y la otra forma es utilizar un captador de esta manera:

myLocalVar = myClass.getMyVarVal(); 

Ambas formas están trabajando muy bien, pero me preguntaba lo sería la forma más eficiente/adecuada de hacer esto?

Gracias

+3

Muchos recursos [aquí] (http://stackoverflow.com/q/1568091/387852), [aquí] (http://stackoverflow.com/q/565095/387852) y [aquí] (http : //stackoverflow.com/q/996179/387852) por ejemplo. –

+0

Pero qué pasa si tengo como 50 variables que describen un objeto. Por ejemplo, digamos que tengo un objeto llamado Car, y luego tengo un montón de variables como carType, carColor, carHP, carMaker, carName, carWheelBase, carMPG, carTransmission, carEngine, etc ... ¿Debo hacer un getter? y setter para cada uno? Parece una TONELADA de codificación adicional ... – SkyeBoniwell

+2

Los IDEs modernos (como Eclipse) pueden hacerlo automáticamente. Pero también debe preguntarse si necesita exponer esas variables al mundo exterior. ¿Estás violando los buenos principios de encapsulación? –

Respuesta

11

Ambas técnicas son terribles, pero utilizando el captador es la práctica común (y más seguro).

Para acceder a un miembro de datos públicos (a.k. un campo público o propiedad pública) de una clase, debe conocer los detalles de implementación de la clase (el nombre del miembro de datos y el tipo de miembro de datos). Esto es algo malo; rompe el concepto de OOP "ocultar información" y aumenta el "acoplamiento".

El uso de un getter también es malo (como en una mala práctica de OOP) porque los objetos no son solo envoltorios alrededor de los datos; se supone que los objetos encapsulan funcionalidad e información. "almacenar este valor aquí para que pueda obtenerlo más tarde" no es una funcionalidad; es la funcionalidad ululante (como en un mono en un ulular de la jaula). Los getters son; sin embargo, una práctica aceptada en Java (y otros lenguajes OOP-lite como C++ y C#).

Para que no pienses que soy una torre de marfil pura, por supuesto que uso getters; Yo uso java, entonces uso getters.

Los getters están bien para hacer el trabajo (sin juego de palabras), simplemente no camines creyendo que "IR gud OOP Prgmr", porque si usas getters no eres un "buen programador de oops", solo eres un programador que hace el trabajo.

Editar: Quizás una mejor manera.

La mejor manera es no utilizar getters, sino diseñar sus clases para que expongan la funcionalidad y no los datos. En la práctica, hay un punto en el que esto se descompone; por ejemplo, si necesita mostrar una dirección en una página JSP, coloca un bean en la solicitud (o sesión o bla) con la dirección y expone los valores usando getters. Una manera "más pura" sería poner un frijol que expuso la funcionalidad "mostrar la dirección en un jsp".

Edit2: Tal vez un mejor ejemplo.

Digamos que trabajo para una compañía telefónica, en los EE. UU., Y tengo un objeto que representa el número de teléfono de un cliente. Esto podría ser como la siguiente:

public class CustomerPhoneNumber 
{ 
    private String npa; // numbering plan area (google search nanp for more details) 
    private String nxx; // exchange. 
    private String serviceNumber; 

    public String toString() 
    { 
    return "(" + npa + ") " + nxx + "-" + serviceNumber; 
    } 

    public boolean equals(Object object) 
    { 
    ... standard equals implementation (assume this works) 
    } 
} 

Ahora dicen que tengo un número de teléfono como una entrada desde una página web en forma String inputPhoneNumber. A los efectos de la discusión, la clase que recibe esta entrada se llama "el servlet".

¿Cómo puedo responder esta pregunta: "¿El número de teléfono de entrada está en mi lista de objetos CustomerPhoneNumber?"

La opción 1 es hacer públicos los miembros de datos npa, nxx, y serviceNumber y acceder a ellos. Este es terrible.

La opción 2 proporciona getters para npa, nxx y número de servicio y los compara con la entrada. También es terrible, demasiados detalles internos expuestos.

La opción 3 proporciona un getter que devuelve el número de teléfono formateado (lo llamé aString() arriba). Esto es más inteligente pero aún terrible porque el servlet debe conocer el formato que utilizará el captador y asegurarse de que la entrada se formatee de la misma manera.

La opción 4 (esto lo llamo "Bienvenido a OOP") proporciona un método que toma una cadena y devuelve verdadero si coincide con el número de servicio al cliente. Esto es mejor y podría tener este aspecto (el nombre es largo, pero suficiente para este ejemplo):

public boolean doesPhoneNumberMatchThisInput(final String input) 
{ 
    String formattedInput; 
    String formattedCustomerPhoneNumber = npa + nxx + serviceNumber; 

    formattedInput = ... strip all non-digits from input. 

    return StringUtils.equals(formattedCustomerPhoneNumber, formattedInput); 
} 

Este es el ganador porque no hay detalles de implementación están expuestos. Además, toString se puede usar para mostrar el número de teléfono en una página JSP.

StringUtils es parte de Apache Commons Lang.

+0

entonces, ¿hay una mejor manera o son consumidores solo un mal necesario? – SkyeBoniwell

+0

Hay un [excelente artículo aquí] (http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html) para aquellos que buscan una explicación más completa (ver el * Una sección de Ball and A Dog * para una analogía muy comprensible.) –

8

En aras de encapsulation siempre hay que ir con la segunda alternativa.

myLocalVar = myClass.getMyVarVal(); 

Eficiencia en lo que probablemente no notarás la diferencia.

4

¡Utilice SIEMPRE getter y setter para acceder a sus propiedades!

También debe echar un vistazo a this.

1

myClass.getMyVarVal() es más lento ya que es una llamada a método y por lo tanto crea entrada en la pila para el valor de retorno, etc. Pero es mejor práctica OOP para usar getters.

+2

El lenguaje Java no dicta que la llamada al método deba implementarse de esa manera. De hecho, lo más probable es que dicho método se inline. – aioobe

1
myLocalVar = myClass.getMyVarVal(); 

que será bueno para usarlo si se está trabajando con el concepto OOP

2

Simplemente crea el objeto y object.variablename; o object.methodName(); se puede utilizar para hacer referencia no estática ... no se requiere el uso de getter.

Cuestiones relacionadas