2010-07-11 17 views
8

Considérese este fragmento de código:Buenas Prácticas para Volviendo referencias a objetos

class MyClass{ 
    private List myList; 
    //... 
    public List getList(){ 
     return myList; 
    } 
} 

como Java pasa referencias de objetos por valor, mi opinión es que cualquier objeto llamando getList() obtendrá una referencia a myList, lo que le permite modificar myList a pesar siendo private. ¿Es eso correcto?

Y, si es correcto, debería estar utilizando

return new LinkedList(myList); 

para crear una copia y pasar de nuevo una referencia a la copia, en lugar del original, con el fin de evitar el acceso no autorizado a la lista referenciada por myList?

+2

técnicamente, ningún cliente externo podrá cambiar el valor del campo myList en su clase. Siempre será un control/referencia a List, haciendo referencia a la lista a la que algún código dentro de MyClass lo configuró.El cliente externo podrá modificar el contenido de esa lista –

+0

Sí, eso es lo que quise decir, pero se volvió un poco descuidado con mi explicación. Lo editaré – chrisbunney

+0

+1 Miro A para una aclaración correcta. Y sí, su solución al crear una copia de la lista es correcta (por lo que quiere lograr). – xagyg

Respuesta

9

Hago eso. Mejor aún, algunas veces devuelvo una copia no modificable usando la API de Colecciones.

Si no lo hace, su referencia no es privada. Cualquiera que tenga una referencia puede alterar su estado privado. Lo mismo ocurre con cualquier referencia mutable (por ejemplo, Fecha).

+3

Si proporciona una vista no modificable de la colección original, tenga en cuenta que cualquier cambio en la lista original se reflejará en la vista. La vida sería mucho más simple con colecciones inmutables ... –

2

Depende de lo que desee.

¿Deseas exponer la lista y hacerlo para que la gente pueda editarla?

¿O desea dejar que la gente lo mire, pero no lo modifique?

No hay una manera correcta o incorrecta en este caso. Solo depende de tus necesidades de diseño.

+0

Por lo tanto, si su diseño dicta que un atributo tiene visibilidad privada, debe devolver una copia del objeto en lugar de una referencia simple para asegurarse de que permanece encapsulado – chrisbunney

+0

@chris Si diseña requiere que las personas no puedan modificar su lista, luego pasen una copia. De lo contrario, pase la referencia original. – jjnguy

+1

Sí, lo siento, fue un comentario retórico, entendí su respuesta;) – chrisbunney

1

Puede haber algunos casos en los que uno quiera devolver la lista "sin formato" a la persona que llama. Pero en general, creo que es una mala práctica, ya que rompe la encapsulación y, por lo tanto, está en contra de OO. Si debe devolver la lista "en bruto" y no una copia, debe ser explícitamente claro para los usuarios de MyClass.

0

Sí, y tiene un nombre .. "Copia defensiva". También se recomienda copiar en el extremo receptor. Como Tom has noted, el comportamiento del programa es mucho más fácil de predecir si la colección es inmutable. Entonces, a menos que tenga una muy buena razón, debe usar una colección inmutable.

Cuando Google Guava se convierte en parte de la biblioteca estándar de Java (estoy totalmente de pensar que debería), esto probablemente se convertirá en el idioma preferido:

return ImmutableList.copyOf(someList); 

y

void (List someList){ 
    someList = ImmutableList.copyOf(someList); 

Esto tiene la ventaja adicional de rendimiento, porque el método copyOf() comprueba si la colección ya es una instancia de colección inmutable (instanceof ImmutableList) y, si es así, omite la copia.

1

Creo que el patrón de hacer que los campos sean privados y proporcionar acceso es simplemente para el encapsulamiento de datos. Si quieres que algo sea realmente privado, ¡no le des métodos de acceso! A continuación, puede escribir otros métodos que devuelvan versiones inmutables de sus datos privados o copias de los mismos.

Cuestiones relacionadas