2010-07-15 16 views
10

Digamos que tengo un tipo llamado Superstar. Ahora quiero tener un método que funcione y edite algunas propiedades de un objeto Superstar.¿Una buena práctica para editar objetos "por referencia"?

Aquí hay dos formas de cómo podría implementar esto. 1 manera sería la siguiente:

private Superstar editSuperstar(Superstar superstar){ 
    .... 
    superstar.setEdited(true); 
    return superstar; 
} 
... 
superstar = editSuperstar(superstar); 

y forma 2 sería la siguiente:

private void editSuperstar(Superstar superstar){ 
    .... 
    superstar.setEdited(true); 
} 
... 
editSuperstar(superstar); 

¿Cuál de estas dos maneras posibles se considera la "mejor práctica"? ¿El primero, o el segundo pseudo "por referencia"?

Respuesta

6

En su caso, la segunda forma es preferible, ya que cambia directamente una de sus propiedades superestrella (edited). Sin embargo, si tiene un método que utiliza un objeto superestrella y devuelve una versión actualizada del mismo (sin cambiar el inicial), el primer formulario tendrá mi favor.

Por último, dado que ambos ejemplos solo usan objetos Superstar, deben ser métodos miembros de la clase Superstar.

+0

esto es tarde, pero el segundo método no edita directamente la 'superestrella' exterior. Crea una versión localizada de 'superstar' y nunca cambia ninguna de las propiedades del objeto externo. – Jon

+1

@Jon ¿Por qué dices eso? No hay nada aquí que respalde esa afirmación, ¿no? – Riduidel

4

Usa el modo 2 a menos que estés creando una clase de "generador" en la que pretendas invocaciones en cadena. Ejemplo:

MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build(); 
+0

Su ejemplo es bastante diferente, más bien ilustra la idea de devolver "this" - en lugar de "void" - desde un método setter para permitir el encadenamiento de invocaciones de setter ... – pgras

4

El primer formulario es engañoso. Da la impresión de que se está transfiriendo un objeto, que se copia y la copia se modifica y devuelve.

"Mejor práctica" sería utilizar el primer formulario, pero para hacer realmente lo que está implícito (aplicar el cambio a una copia, que luego se devuelve). Los objetos inmutables generalmente deberían preferirse a los objetos mutables, a menos que sean objetos grandes y costosos de copiar, en cuyo caso, debería favorecer la segunda forma.

2

El problema que tenemos aquí con el primer método es si lo usa así:

Superstar edited = editSuperstar(originalSuperstar); 

Esto también modificará el originalSuperstar que es, en mi opinión, contrario a la intuición ...

lo tanto prefieren el segundo si modifica el objeto pasado o el primero si devuelve una copia nueva del objeto.

Para este peculiar ejemplo, usted podría simplemente añadir un método de edición a la clase Superstar ...

1

La primera forma sería sorprendente que los clientes de la API si devuelve la misma instancia que tiene solamente cambiado algunos campos. Uno esperaría recuperar una copia modificada sin tener que cambiar la instancia original.

Utilice el segundo formulario si no devuelve una copia y use la primera si lo hace (y piense en hacer que Superstar sea inmutable en ese caso).

Cuestiones relacionadas