2010-05-26 17 views
7

Un colega mío y yo tuvimos una conversación sobre el siguiente tema de mejores prácticas.
La mayoría de las funciones/métodos comienzan con la comprobación de algunos parámetros.Estilo de si: anidar o no anidar

Defiendo el siguiente estilo, que evita la anidación.

if (parameter one is ugly) return ERROR; 
if (parameter two is nonsense || it is raining) return ERROR; 
// do the useful stuff 
return result; 

Él, que proviene de un entorno de programación más funcional/lógico, prefiere la siguiente, ya que reduce el número de puntos de salida de la función.

if (parameter one is ok) { 
    if (parameter two is ok && the sun is shining) { 
     // do the useful stuff 
     return result 
    } 
} 
return ERROR; 

¿Cuál prefieres y por qué?

+3

El uso de las cláusulas Guard es aconsejable. Verifique la regla de refactorización de Fowlers: http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html - transforma su segundo (anidado) en el primero (cláusula de guardia). – Konerak

Respuesta

0

El segundo prefiero generalmente, a menos que todo el cuerpo de la función se envuelva en el número X de if declaraciones. Si es así, elegiría la primera opción.

5

Siempre que el estilo sea uniforme en la base de código, cualquiera de estos dos estilos estaría bien conmigo.

0

Prefiero el primero. 5298529357 niveles de sangrado solo irritan mis nervios.

Agregue a eso el hecho de que cuando regrese de inmediato, es obvio que (el parámetro uno es feo) es un error.

1

Prefiero hacer toda mi validación de parámetros de entrada al comienzo de la función y hacer un solo return allí. Por lo tanto, prefiero el primer enfoque la mayoría de las veces. Si solo hay un nivel de anidación, entonces podría ir por la segunda opción.

12

Personalmente prefiero el primer estilo, ya que creo que proporciona una cierta separación lógica entre lo que podemos llamar "casos de error" y "lógica de método". Hay un bloque bien definido en el comienzo del método que evalúa y actúa sobre cualquier error en la entrada, y luego el resto del método se trata de lo que realmente debería hacer el método.

Es una especie de separación de preocupaciones en el nivel micro, supongo.

0

El estilo más legible es:

if (parameter one is ok) 
{ 
    if (parameter two is ok && the sun is shining) 
    { 
     // do the useful stuff 
     return result 
    } 
    else 
    { 
     // do other things 
    } 
} 
return ERROR; 

Al menos para mí :)

EDIT: Lo sentimos, entendido mal la pregunta. Voto por el primero, no me gusta la anidación profunda.

2

En el caso de dos controles, entonces, o bien está bien, una vez que agregue más, la opción 1 se vuelve cada vez más deseable.

0

En mi opinión, solo depende del tipo de verificación de errores que necesite.
Si, por ejemplo, el parámetro uno es ugly pero en el siguiente código puede administrar cambiar su estado a pretty es preferible el segundo método.
Sin embargo, si el error es fatal y no se puede manejar, debe devolverlo inmediatamente.
Hay una tercera opción aquí donde el segundo estilo se ajusta más y es cuando desea reunir todos los errores en un mensaje de error coherente.
El segundo estilo no debe verificar primero la validez sino la no validez.
En cuanto a las preferencias personales, sería mucho más feliz con el primer estilo.

0

Nuestro estilo de la casa es para evitar múltiples return puntos y también para limitar la cantidad de anidación, así que probablemente combinar su condición previa cordura comprueba juntos y hacer algo como:

result_t result = OKAY;  

// Sanity checks 
if ((parameter_one == ugly) || (parameter_two == nonsense) || (weather == raining)) 
{ 
    result = ERROR; 
} 
else 
{ 
    // do the useful stuff 
} 

return result; 
Cuestiones relacionadas