2008-11-24 19 views

Respuesta

46

me gusta para eliminar casos de error primero - y retorno de la función temprana para que el 'camino feliz' sigue siendo un-anidado, por ejemplo

if (some error condition) 
{ 
    //handle it 
    return; 
} 
//implicit else for happy path 
... 

si es fácil de identificar las condiciones que conducen a la trayectoria feliz, entonces por todos los medios poner esa cláusula primera (gracias Marcin!)

+2

Buena respuesta. Este patrón se conoce comúnmente como una "cláusula de guardia". –

+0

Lo siento, no puedo estar de acuerdo con esto en absoluto. Por favor, mira mi respuesta a continuación. – Marcin

+0

@DLarsen: respuesta editada para reflejar el consejo de Marcin también –

4

si sus líneas 1 o 2 y un pronto regreso, me Lo pondría en la parte superior, especialmente si está al principio de la función. eso casi parece un contrato. de lo contrario, voy con la regla de "condiciones positivas antes negativas".

0

Depende de lo que es más claro para usted. Quiero decir, lo que tiene más sentido, que noProblems tiene un valor verdadero o que tiene un valor falso.

Por ejemplo para isDeviceEnabled() Siempre verificaría un resultado verdadero, ya que "Activado" tiene implícitamente un valor positivo. Para un valor negativo implícito, podríamos verificar, por ejemplo, "isMemoryAvailable()", tal vez porque necesita verificar solo si no hay más espacio para nuevos objetos/matrices u otros datos.

0

Es un tipo de decisión muy individual, pero tiendo a poner mis condiciones de error primero, con el pretexto de agrupar como código juntos. Es decir, si hago algo, y falla, el control de ese error es realmente parte de hacer eso; si pongo el cheque de falla y acción basado en eso al principio de mi código, he agrupado mi acción y la compleja respuesta a esa acción en conjunto (trabajando en la suposición de que un resultado de falla es en realidad un caso de devolución más complejo que un éxito).

0

El primero me parece ligeramente preferible ya que evita un doble negativo en el condicional.

Aparte de eso, que hemos construido cosas, para que pueda realmente no

// do stuff 

después

// deal with problem 

así que más allá de que uno parece tan bueno como el otro.

0

Como con try/catch Realizo el flujo normal y luego manejo las condiciones de excepción.

Eso no significa que la comprobación/borrado de errores no ocurra primero, pero eso es si no confío en lo que me han pasado.

por ejemplo,

if (foo is null) then 
    // bail 
end if 

if (bar == foo) then 
    // foo hasn't been changed... print the regular report 
else 
    // foo has changed, run the reconciliation report instead. 
end if 

me gusta la historia feliz fluya como una línea recta, y la triste historia de escindir a su propia espuela.

7

Quizás esto dependa de las convenciones del lenguaje u otros factores, pero creo que el caso nominal debe estar en la parte superior, y las ramas deben contener las condiciones excepcionales. Hace que el código sea mucho más fácil de leer.Esto es especialmente cierto cuando hay muchas condiciones excepcionales, y en la mayoría de los casos las hay. Podrá asumir fácilmente que el autor espera que esta ruta específica se tome la mayor parte del tiempo, y comprender el código más fácil de esta manera.

Desde la sección "Código completo, 2ª edición" 15.1:

Al poner en primer lugar los casos más comunes, se minimiza la cantidad de código de manejo de alguien excepción de los casos tiene que leer para encontrar los casos habituales. Mejore la eficiencia porque minimiza el número de pruebas que hace el código para encontrar los casos más comunes.

+6

También puede leer la sección 17.1, que dice: "Usar cláusulas de protección (salidas o salidas anticipadas) para simplificar el procesamiento complejo de errores" –

+0

Estoy de acuerdo en el caso cuando es fácil identificar las condiciones que conducen al camino feliz, editaré mi respuesta para reflejar su sabiduría adicional –

0

por qué no crear un punto de salida de la función y hacer limpieza adecuada allí en vez de tener múltiples retornos ...

 

DWORD bRetVal= TRUE; 
if(foo is null) 
{ 
    bRetVal = FALSE; 
    goto Error; 
} 
else 
{ 
// do something 
} 

Exit: 
return bRetVal; 

 
Cuestiones relacionadas