2009-05-19 11 views
5

duplicado:Should a function have only one return statement?¿Mejor método de Java Sintaxis? ¿Regresas temprano o tarde?

Muchas veces es posible que tenga un método que comprueba numerosas condiciones y devuelve un estado (digamos booleano por ahora). ¿Es mejor para definir una bandera, establecido durante el método, y devolverlo al final:

boolean validate(DomainObject o) { 
    boolean valid = false; 
    if (o.property == x) { 
    valid = true; 
    } else if (o.property2 == y) { 
    valid = true; 
    } ... 
    return valid; 
} 

o es mejor/más correcto para volver simplemente una vez que conozca el resultado del método?

boolean validate(DomainObject o) { 

    if (o.property == x) { 
    return true; 
    } else if (o.property2 == y) { 
    return true; 
    } ... 
    return false; 
} 

Ahora, obviamente, podría haber bloques try/catch y todos los demás tipos de condiciones, pero creo que el concepto es claro. Opiniones?

+0

¿Solo una propiedad tiene que ser válida para que todo sea válido? –

+0

duplicado http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement –

+0

otro enlace http://stackoverflow.com/questions/124122/single-return-or- multiple-return-statements-closed –

Respuesta

7

Si es un método que va a llamar miles de veces, entonces el retorno anticipado es mejor para lograr un rendimiento [ligeramente] mayor.

De lo contrario, preferiría el retorno tardío, ya que mejora la legibilidad.

Recuerde que los programadores suelen pasar más tiempo leyendo que escribiendo códigos, por lo que cualquier cosa que pueda hacer para mejorar la legibilidad será ciertamente bienvenida.

+21

¿Cómo es que el retraso es más legible? Para mí es complicado regresar tarde. De ello infiero que el método no está hecho haciendo lo que necesita si no ha regresado. –

+0

Es más legible porque no se corta el flujo del proceso en el medio. En su lugar, guarda el estado y regresa al final del método. – Seb

+7

Encuentro que la bandera es menos legible precisamente porque debe seguir exactamente cada condición, llamada de método, etc. para saber si alguien más tocó la bandera antes de regresar, mientras que con la otra alternativa está seguro de que cuando la propiedad es x se hará realidad, no importa qué más suceda allí. –

1

Para mí, este es uno de esos temas de guerra religiosa sin una respuesta correcta. El argumento en contra de regresar temprano esencialmente se reduce al hecho de que tener un solo punto donde una función puede salir reduce el número de caminos posibles a través de su código, por lo menos, al menos en teoría, reduciendo las posibilidades de errores. Mi estilo personal es, en situaciones en las que tiene sentido volver temprano hacerlo, y en situaciones en las que tiene sentido limitar a una declaración de devolución, lo hago.

0

Personalmente, me gusta mejor el segundo método. Es directo y claro para mí, pero sé que hay personas que deben tener solo un retorno en una función.

5

Al igual que con la mayoría de los estilos de codificación, es realmente una cuestión de preferencia, pero guard clauses son considerados por muchos como las mejores prácticas.

+0

Esto no es una cuestión de cláusula de guardia; se trata de devolver diferentes valores según los parámetros. Nadie habló sobre parámetros correctos o incorrectos, o la necesidad de tener condiciones previas. – Seb

+0

@Seb: las cláusulas de Guard son similares, no iguales a las condiciones previas.Las cláusulas de Guard no están restringidas a la validación de parámetros, tampoco. Puede usar una cláusula de guardia para regresar rápidamente en casos triviales, lo que da como resultado puntos de retorno múltiples, de lo que se trata la pregunta. –

1

Si las excepciones no son parte de la imagen, prefiero regresar inmediatamente cuando pueda.

Puede ser fácil administrar mal la variable de indicador y estoy en contra de las variables de indicador en general. No regresar también podría hacer que un mantenedor piense que se puede hacer más trabajo (si el método es largo).

0

Honestamente, creo que depende de la situación. Personalmente uso ambos, y decido basado en cuál hará que el código sea más claro y fácil de leer.

Si en gran medida han anidado si las declaraciones (o cualquier otra estructura de control) y que pueden prestarse a confusión, entonces me volvería dentro de las declaraciones

No se preocupe demasiado acerca de lo que es 'mejor práctica' en este caso, ya que es más importante que el código sea claro y fácil de entender. Use lo que se sienta bien para la situación.

8

Prefiero regresar temprano y evitar la anidación profunda. Esto es particularmente cierto al comienzo del método: prueba cualquier cosa que sea simple, y sal de ahí (o lanza una excepción) si puedes hacerlo muy temprano.

Si está justo en el medio de un método, es más una decisión de juicio.

Tenga en cuenta que me refactorizar su ejemplo de inmediato a utilizar un único if:

boolean validate(DomainObject o) {  
    if (o.property == x || o.property2 == y) { 
    return true; 
    } ... 
    return false; 
} 

Me di cuenta que era sólo un ejemplo de juguete, pero mi punto es que siempre vale la pena buscar más formas de simplificar su código :)

0

para este caso, prefiero:

boolean validate (DomainObject o) { 
    if (o.property == x || 
     o.property2 == y || 
     ...) { 
      return true; 
    } else { 
      return false; 
} 

En general, me gusta usar pronto retorno para manejar condiciones de error, y el regreso al final para devolver los resultados calculados.

0

Hay dos factores tirando uno contra el otro.

El primer factor es la facilidad de depuración. Si regresa inmediatamente (como se muestra en el segundo fragmento de código), a veces resulta difícil depurar una función grande ya que es difícil encontrar estas declaraciones de devolución, especialmente si se pusieron allí por error.

El segundo factor es la facilidad de implementación. Si está comprobando la corrección básica de los argumentos al comienzo de la función y hay un fragmento largo de código antes de que la función finalice, es posible que deba poner ese código completo en un bucle de condición. Si no lo hace, en algún momento el argumento podría ser utilizado para un cálculo largo, perdiendo tiempo, porque finalmente sería rechazado de todos modos.

Por lo tanto, la respuesta podría ser así:

If the function is small, 
     save the return status in a variable and return at the end. 
else 
     return immediately. 
4

La única vez que yo diría que definitivamente no debe regresar temprano es que si no puede ver fácilmente cada vuelta dentro de una única pantalla (sea cual sea el el estándar puede ser para personas que trabajan en la misma base de código), al menos debe agregar comentarios que indiquen que la función puede regresar temprano si hay un retorno anticipado.

La única vez que yo diría que sin duda debe regresar temprano es si su código es el siguiente ...

boolean valid = true; 
if(condition1) { 
    valid = false; 
} 
if(valid) { 
    ... 
    if(condition2) { 
     valid = false; 
    } 
} 
if(valid) { 
    ... 
    if(condition3) { 
     valid = false; 
    } 
} 
... (etc) 

Si usted se encuentra en cualquiera de estas situaciones, sin embargo ... probablemente debería ser refactorización la función.

+0

+1 para su última línea; de hecho, debería extraer métodos más pequeños si la función llega a ser demasiado larga. – Hace

Cuestiones relacionadas