2012-06-27 12 views
7

que estábamos teniendo esta discusión wiht mis colegas acerca de las asignaciones internas tales como:¿Es malo hacer tareas internas?

return result = myObject.doSomething(); 

o

if (null == (point = field.getPoint())) 

Son estos aceptable o en caso de que se sustituye por el siguiente y por qué?

int result = myObject.doSomething(); 
return result; 

o

Point point = field.getPoint(); 
if (null == point) 
+1

Supongo que 'result' en el primer caso es miembro de una clase en lugar de una variable local. De lo contrario, la asignación es redundante. – nhahtdh

+0

@nhahtdh redundante tal vez, pero el código es más claro y este fue nuestro código de discusión más clara o más conciso? –

+0

Lo sé, pero desde que mencionaste el reemplazo, solo tuve que comentar. – nhahtdh

Respuesta

20

La asignación interna es más difícil de leer y más fácil de perder. En una condición compleja, incluso se puede perder, y puede causar un error.

Ej. este será un error difícil de encontrar, si la evaluación de la condición a evitar asignar un valor a la variable:

if (i == 2 && null == (point = field.getPoint())) ... 

Si i == 2 es falso, la variable de coma no tiene valor más adelante.

+0

cómo podría causar un error – vedant1811

+0

Ejemplo adjunto, la variable de punto no puede contener valor si la condición falla prematuramente. – Matzi

+2

&& y || es la evaluación de cortocircuito, eso significa que si i! = 2, punto = campo.getPoint() no será evaluado –

6

Esta es ocupa principalmente de mejor legibilidad del código. Evitar las tareas internas para hacer su código legible como usted no recibirá mejoras con las tareas internas

5

FuncionalmenteNot Necessarily. para legibilidadDefinitely Yes

1

no encuentro ningún daño en el uso de las asignaciones internas. Ahorra pocas líneas de código (aunque estoy seguro de que no mejora el tiempo de compilación o ejecución ni la memoria). El único inconveniente es que para otra persona puede parecer engorroso.

3

Bueno, el primero no es exactamente la asignación interna, pero en el segundo caso se reduce la legibilidad ... ... pero en algunos casos como el de abajo,

while (null == (point = field.getPoint())); 

que es bueno para escribir de esta manera

2

siempre funcionan y tienen como objetivo para el código legibilidad no capacidad de escritura. Lo mismo vale para cosas como a > b ? x : y; Probablemente hay muchos desarrolladores por ahí no tienen problemas de lectura de su primera snipet código, pero la mayoría de ellos se utilizan para la segunda snipet.

3

En ambos casos, la primera forma es más difícil de leer, y le hará desea cambiarlo cada vez que desea examinar el valor en un depurador. No sé con qué frecuencia he maldecido el código "conciso" al depurar los pasos.

2

La forma más prolija también hace que sea más fácil de seguir en un depurador como Eclipse. A menudo me divido asignaciones de una sola línea para que los valores intermedios sean más fácilmente visibles.

Aunque no directamente solicitada por OP Un caso similar es función llama como los argumentos del método pueden ahorrar líneas, pero son más difíciles de depurar:

myFunction(funcA(), funcB()); 

no muestra los tipos de retorno y es más difícil de recorrer.También es más propenso a errores si los dos valores son del mismo tipo.

8

if (null == (point = field.getPoint()))

Pros:

  • Uno menos línea de código

Contras:

  • menos legible.
  • No restringe el alcance point a la instrucción y su bloque de código.
  • no ofrece mejoras en el rendimiento por lo que yo soy consciente
  • no siempre puede ser ejecutado (cuando hay una condición que le precede que se evalúa como falsa.

contras superan a los pros 4/1 por lo yo evitaría que

5

deben evitarse la reducción del número de identificadores/operaciones por línea aumentará la legibilidad y mejorar la calidad del código interno he aquí un interesante estudio sobre el tema:... http://dl.acm.org/citation.cfm?id=1390647

Así bot línea de tom, división

return result = myObject.doSomething(); 

en

result = myObject.doSomething(); 
return result; 

hará que sea más fácil para que otros puedan entender y trabajar con su código. Al mismo tiempo, no sería el fin del mundo si hubiera un par de asignaciones internas salpicadas a lo largo de su base de código, siempre y cuando sean fácilmente comprensibles dentro de su contexto.

+0

Pero, ¿por qué no utilizar simplemente 'return myObject.doSomething();' en ese caso? – Line

+0

Sí, eso suele ser mejor. Solo haría una asignación intermedia cuando trate cadenas de métodos largos/complejos. En esos casos, el nombre de la variable puede servir como documentación. – fedenusy

+0

Me gusta esa manera una vez, pero Sonar se queja de eso, de ahí es de lo que tengo esta idea que es mala. – Line

3

Hay muy pocos casos en que las asignaciones internas reducen la complejidad del programa, por ejemplo en if (x != null && y != null && ((c = f(x, y)) > 0) {...} y realmente solo necesita la asignación en el caso cuando se ejecuta en la condición compleja.

Pero en la mayoría de los casos las asignaciones internas reducen la legibilidad y se pueden perder fácilmente.

Creo que las asignaciones internas son una reliquia de las primeras versiones del lenguaje de programación C en los años setenta, cuando los compiladores no hicieron ninguna optimización, y el trabajo para optimizar el código se dejó a los programadores. En ese momento, las asignaciones internas eran más rápidas, porque no era necesario volver a leer el valor de la variable, pero hoy en día con computadoras rápidas y compiladores de optimización, este punto ya no cuenta. Sin embargo, algunos programadores de C estaban acostumbrados a ellos. Creo que Sun introdujo asignaciones internas a Java solo porque querían ser similares a C y facilitar que los programadores de C cambien a Java.