2011-02-03 10 views
13

He leído (por ejemplo, de Martin Fowler) que debemos usar la cláusula de guardia en lugar del retorno único en un método (corto) en OOP. También he leído (de algún lugar que no recuerdo) que la cláusula else debería evitarse cuando sea posible.¿Debo usar la cláusula de guardia e intentar evitar la cláusula else?

Pero mis colegas (trabajo en un pequeño equipo con solo 3 tipos) me obligan a no usar múltiples devoluciones en un método, y usar la cláusula else tanto como sea posible, incluso si solo hay una línea de comentario en el bloque de otra manera.

Esto me dificulta seguir su estilo de codificación, porque, por ejemplo, no puedo ver todo el código de un método en una pantalla. Y cuando codigo, primero tengo que escribir la cláusula de guardia, y luego trato de convertirla a la forma sin retornos múltiples.

¿Estoy equivocado o qué debo hacer con él?

+0

Con _ "No puedo ver todo el código de un método en una pantalla" _, ¿quiso decir que lo han hecho tanto que el código se ha sangrado tanto que se sale del borde derecho del ¿pantalla? ¿O que if-else ocupa un poco más de espacio por lo que el método es más largo (más alto) de lo que necesita ser? B.t.w. Me gustan las cláusulas de guardia. – KajMagnus

+0

* "incluso si solo hay una línea de comentario en el bloque else" *: una fuente para esto proviene del libro Code Complete. Aunque parece que son demasiado dogmáticos para aplicarlo. – icc97

Respuesta

29

Esta es una pregunta estética discutible y pura.

El retorno anticipado se ha evitado históricamente en C y en lenguajes similares, ya que era posible omitir la limpieza de recursos, que generalmente se coloca al final de la función en caso de devolución anticipada.

Dado que Java tiene excepciones y trata de atrapar, finalmente, no hay necesidad de temer los retornos tempranos.

Personalmente, estoy de acuerdo con usted, ya que a menudo vuelvo temprano - eso generalmente significa menos código y un flujo de código más simple con menos anidamiento si/no.

+2

Si mi memoria me sirve, otra razón para evitar los retornos iniciales (o rupturas de bucles) fue que era más fácil teóricamente probar que su código era correcto. (a.k.una verificación formal) – biziclop

+9

+1 para señalar que es discutible. Prefiero el regreso temprano, también, para la legibilidad. –

+0

Prefiero el retorno anticipado, también, siempre que adopte la forma de cláusulas de guardia, y no dé lugar a numerosas declaraciones nebulosas de "devolución". Salir de un bucle for, por ejemplo, está perfectamente bien. 'for (Object o: objects) {if (someCondition) {return o; }} ' –

4

Haga que lean http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt y vea si cambia de opinión. (Hay una historia para su idea, pero estoy del lado de usted.)

Edit: Aquí están los puntos críticos del artículo. El principio de las salidas individuales de las estructuras de control se adoptó en principio, no como datos de observación. Pero los datos de observación dicen que permitir múltiples formas de salir de las estructuras de control hace que ciertos problemas sean más fáciles de resolver con precisión y no perjudica la legibilidad. No permitirlo hace que el código sea más difícil y más probable que tenga errores. Esto se aplica a una amplia variedad de programadores, desde estudiantes hasta escritores de libros de texto. Por lo tanto, deberíamos permitir y usar salidas múltiples cuando corresponda.

+0

Hay demasiado para leer en ese artículo. ¿Puedes mencionar la idea esencial? – HelloWorldNoMore

+1

@HelloWorldNoMore El principio de las salidas individuales de las estructuras de control se adoptó por principio, no como datos de observación. Pero los datos de observación dicen que permitir múltiples formas de salir de las estructuras de control hace que ciertos problemas sean más fáciles de resolver con precisión y no perjudica la legibilidad. No permitirlo hace que el código sea más difícil y más probable que tenga errores. Esto se aplica a una amplia variedad de programadores, desde estudiantes hasta escritores de libros de texto. Por lo tanto, deberíamos permitir y usar salidas múltiples cuando corresponda. – btilly

1

Estoy en el campamento de retorno múltiple/regreso temprano y presionaría para convencer a otros ingenieros de esto. Puede tener grandes argumentos y citar grandes fuentes, pero al final, todo lo que puede hacer es hacer su presentación, sugerir compromisos, tomar una decisión y luego trabajar en equipo, en cualquier caso que funcione. (Aunque volver a visitar el tema de vez en cuando tampoco está fuera de discusión.)

Esto realmente se reduce al estilo y, en el gran esquema de las cosas, es relativamente menor. En general, eres un desarrollador más efectivo si puedes adaptarte a cualquier estilo. Si esto realmente "hace que sea difícil ... seguir su estilo de codificación", entonces le sugiero que trabaje en él, porque al final, terminará siendo el mejor ingeniero.

Tuve un ingeniero una vez que vino a mí e insistió en que se le otorgara una dispensación para seguir su propio estilo de codificación (y teníamos un conjunto mínimo de pautas). Dijo que el estilo de codificación establecido le lastimaba los ojos y le dificultaba concentrarse (creo que incluso pudo haber dicho "náuseas".) Le dije que si iba a trabajar con un código de mucha gente, no solo codificaría él escribió, y viceversa. Si no podía adaptarse al trabajo con el estilo acordado, no podría usarlo y quizás este tipo de proyecto de colaboración no era el lugar adecuado para él. Casualmente, fue un problema menor después de eso (aunque cada revisión del código todavía era una batalla).

6

La cláusula de guardia es una buena idea porque indica claramente que el método actual no está interesado en ciertos casos. Cuando borra al principio del método que no se ocupa de algunos casos (por ejemplo, cuando algún valor es menor que cero), entonces el resto del método es la implementación pura de su responsabilidad.

Hay un caso más fuerte de cláusulas de guardia: afirmaciones que validan la entrada y arrojan excepciones cuando algún argumento es inaceptable, p. nulo. En ese caso, no desea continuar con la ejecución, pero desea lanzar al principio del método. Ahí es donde las cláusulas de protección son la mejor solución porque no desea mezclar la lógica de lanzamiento de excepción con el núcleo del método que está implementando.

Cuando hablamos de las cláusulas de guardia que arrojan excepciones, aquí hay un artículo sobre cómo se pueden simplificar en C# utilizando los métodos de extensión: How to Reduce Cyclomatic Complexity: Guard Clause. Aunque ese método no está disponible en Java, es útil en C#.

Cuestiones relacionadas