A menudo me he encontrado con errores causados por el uso de la ELSE
construcción. Un buen ejemplo es algo similar a:
If (passwordCheck() == false){
displayMessage();
}else{
letThemIn();
}
Para mí esto grita problema de seguridad. Sé que es probable que passwordCheck sea booleano, pero no pondría la seguridad de mis aplicaciones en él. ¿Qué pasaría si es una cadena, int, etc.?
Por lo general, trato de evitar el uso ELSE
, y en su lugar opto por dos declaraciones IF completamente separadas para probar lo que espero. Cualquier otra cosa se ignora O se maneja específicamente.
Seguramente esta es una mejor manera de evitar errores / problemas de seguridad que ingresan a su aplicación.
¿Como lo hacen ustedes?
self-improvement
programming-practices
security
billy.bob
fuente
fuente
I know that passwordCheck is likely to be a boolean...
¿Qué quieres decir? En cualquier lenguaje de tipo fuerte.passwordCheck
será lo que quieras que sea.else
declaraciones ...passwordCheck()
posiblemente no sea booleano (lo que puede ser una preocupación razonable), y luego lo culpaelse
. No veo qué problemas laselse
causas.Respuestas:
El
else
bloque siempre debe consistir en lo que desea que sea el comportamiento predeterminado.No hay necesidad de evitarlos, solo tenga cuidado de usarlos adecuadamente.
En su ejemplo, el estado predeterminado debería ser no permitir el acceso. Un poco de refactorización te deja con:
es decir, si la verificación de contraseña funciona, déjelos entrar, de lo contrario siempre es válido mostrar algún mensaje de error.
Por supuesto, puede agregar verificaciones adicionales a su lógica mediante el uso
else if
deif
declaraciones en lugar de declaraciones completamente separadas .fuente
passwordCheck
podría ser cualquier cosa, Fenull
, lo que haríapasswordCheck == false
quefalse
y sería permitir que el usuario de inicio de sesión a causa de un error interno.if
requiere abool
, las variables deben asignarse definitivamente, todas las rutas deben devolver un valor, etc. No se me ocurre ninguna razón por la que el ordenif
y laelse
importancia sean importantes. Es decir,if(a){b();}{c();}
debería ser equivalente aif(!a){c();{b();}
. En JavaScript, por otro lado, debes tener en cuenta quepasswordCheck
podría serundefined
, etc.No, no hay nada de malo
ELSE
.ELSE
No es lo nuevoGOTO
. De hecho, usar dosIF
s en lugar deELSE
puede generar varios problemas.Ejemplo uno:
¿Ves el copiar y pegar? Solo espera el día en que cambies uno y olvides el otro.
Ejemplo dos:
Como puede ver, el segundo
IF
también se ejecutará para el primer elemento, porque la condición ya ha cambiado. En los programas del mundo real, estos errores son más difíciles de detectar.fuente
if
declaración e invertir su expresión booleana solo para evitar unaelse
, ¡ eso es una mala programación! No sólo está duplicando código ( mala programación), que está también ralentizar el rendimiento (si el cheque es realmente complicado, que está ahora haciendo dos veces - ba-- eh, bueno, ya sabes lo que dicen de optimizaciones prematuros hoy en día ... ¡ no tan buena programación!).Siempre hay un ELSE. Si tú escribes
en realidad escribes
Cualquier cosa que ponga en el camino de ELSE es su responsabilidad.
fuente
Personalmente, tiendo a evitar
else
todo lo que pueda, pero no es por ningún problema de seguridad .Al leer el código, las declaraciones anidadas hacen que sea más difícil seguir la lógica, porque debe recordar qué conjunto de condiciones conducirá allí. Por esta razón, soy un gran fanático de la salida anticipada:
Esto también se aplica a las
for
ywhile
los bucles en el que voy a utilizarcontinue
, ybreak
cada vez que se evita un nivel de sangría.Chris Lattner lo dice mejor que yo en los estándares de codificación LLVM .
fuente
*writes an answer*
Entonces solo reemplácelos,
fuente
If ((passwordCheck == true) == true)
? :-)Al igual que Matthieu M., prefiero la salida temprana a los bloques más anidados ... Ilustra una buena programación defensiva (si hay malas condiciones, no tiene sentido continuar). Mucha gente no estará de acuerdo con nosotros, prefiriendo un punto de salida único; No es el punto del debate (creo).
Ahora, ciertamente lo uso
else
cuando tiene sentido, particularmente para alternativas simples y cortas. Como se dijo, duplicar la prueba es una pérdida de tiempo (programador y CPU), una fuente de confusión y, más tarde, de errores (cuando se cambia uno, no el otro).En algún momento, agrego un comentario en la
else
parte, recordando cuál era la condición (particularmente si laif
parte es larga, por ejemplo, en código heredado) o cuál es la alternativa.Tenga en cuenta que algunos defensores extremos de la programación funcional proponen deshacerse por completo
if
, a favor de la coincidencia de patrones ... Un poco demasiado extremo para mi gusto. :-)fuente
No hay nada de malo en usar ELSE. Sin embargo, puede conducir a un código demasiado complejo que es difícil de leer y comprender. Puede indicar un mal diseño. Ciertamente indica casos de uso adicionales que deberán ser probados.
Intenta eliminar ELSEs si puedes, pero no seas paranoico al respecto. Steve McConnell llama a este código de línea recta en Code Complete. Es decir, hay un camino simple y claro a través de su código.
Enfoques para tratar su problema particular:
En general, lo siguiente puede ayudar a reducir ELSE en su código:
fuente
Su suposición acerca de que el código es una fuga de seguridad puede o no ser cierta dependiendo del idioma que esté utilizando. En el código C podría ser un problema (particularmente porque en C un booleano es solo un int que no es cero o cero), pero en la mayoría de los lenguajes fuertemente tipados (es decir, la verificación del tipo de tiempo de ejecución) si la
passwordCheck
variable se declara como booleana, no hay forma de asignarle algo más. De hecho, todo en unif
predicado debe resolverse en un valor booleano, ya sea que use los operadores booleanos o simplemente use el valor. Si logras tener otro tipo de objeto vinculado alpasswordCheck
tiempo de ejecución, arrojarás algún tipo de excepción de lanzamiento ilegal.Las construcciones if / else simples son mucho más fáciles de leer que las construcciones if / if, y menos propensas a problemas inadvertidos si alguien intenta voltear la construcción. Tomemos el mismo ejemplo por un segundo:
Se pierde el significado de las cláusulas mutuamente excluyentes que desea ejecutar arriba. Eso es lo que transmite la construcción if / else. Dos ramas de ejecución mutuamente excluyentes, donde una de ellas siempre se ejecutará. Esta es una parte importante de la seguridad: garantizar que no haya forma de hacerlo
letThemIn
después de haber llamadodenyAccess
.A los efectos de la claridad del código y para garantizar que las secciones críticas estén más protegidas, deben estar dentro de la cláusula primaria (la
if
parte). El comportamiento no conforme predeterminado debe estar en la cláusula alternativa (laelse
parte). Por ejemplo:NOTA: al trabajar con diferentes idiomas, he desarrollado un habbit de codificación que ayuda a evitar la pregunta "¿y si es una cadena?" Esencialmente, es poner la constante primero en la expresión booleana. Por ejemplo, en lugar de verificar
passwordCheck == false
, estoy revisandofalse == passwordCheck
. Esto también evita el posible problema de asignación accidental en C ++. Usando este enfoque, el compilador se quejará si escribo en=
lugar de==
. En lenguajes como Java y C #, el compilador trataría la asignación en la cláusula if como un error, pero C ++ lo aceptará con gusto. Es por eso que también tiendo a hacer una verificación nula con elnull
primero.Si cambia rutinariamente los idiomas, colocar la constante primero es muy útil. Sin embargo, en mi equipo es opuesto al estándar de codificación y el compilador detecta esos problemas de todos modos. Puede ser un hábitat difícil de romper.
fuente
Decir que usar
else
cuando programar es malo es como decir que usarotherwise
cuando hablar es malo.Claro, ambos se pueden usar de mala manera, pero eso no significa que se deben evitar solo porque cometió un error que los incluyó. No me sorprendería si muchos errores dependieran de un
default
caso perdido en unaswitch
declaración.fuente
Piense
Else
en una lista blanca del flujo de su aplicación. Verifica las condiciones que DEBEN permitir que el flujo de la aplicación continúe, y si no se cumplen, entoncesElse
se ejecuta para resolver el problema, suspender la ejecución de la aplicación o algo similar.Else
en sí mismo no es malo, pero si lo usa mal, puede ver efectos no deseados.Además, con respecto a su declaración sobre
"Sé que es probable que PasswordCheck sea booleano, pero no pondría la seguridad de mis aplicaciones en él".
Para los métodos que desarrolle, SIEMPRE devuelva un tipo de datos. Aunque PHP Core está lleno de código que devuelve dos o más tipos de datos, esta es una mala práctica ya que hace conjeturas de las llamadas a funciones. Si tiene que devolver más de un tipo de datos, considere lanzar una excepción (creo que esta es a menudo la razón por la que me gustaría devolver otro tipo de datos, algo salió horrible, terriblemente mal), o considere reestructurar su código para que pueda devuelve solo un tipo de datos.
fuente
Ante todo. Jajaja NO HAY RAZÓN para evitar otra cosa, en absoluto. NO es una mala práctica de ninguna manera o forma.
En todo caso, el código debería ser
No hay dos si hay y no tiene más. Esto es lo que hago en todas mis aplicaciones, excepto en una en la que lanzo una excepción. La excepción está atrapada en mi función que verifica la url para que se muestre la página adecuada (o, alternativamente, puedo poner la función de error catch / check en asp.net). Imprime una página genérica que dice no autorizar o cualquier mensaje que use en la excepción (siempre verifico el tipo de excepción y establezco el código de estado http).
-Editar- como se muestra en el ejemplo de ammoQ dos ifs es ridículo. Realmente lo demás es tan bueno o mejor que un if. Si hay algo que se debe evitar (aunque personalmente no lo hago. Pero uso return and break much), como se ha dicho, más rutas de código aumentan la probabilidad de errores. Ver complejidad ciclomática
-Editar 2- Si te preocupa el uso de if / else. También notaré que mi preferencia es poner el bloque de código más corto en la parte superior, como
En lugar
fuente
Me gusta establecer un valor predeterminado antes de condicionales cuando puedo. Siento que es un poco más fácil de leer y un poco más explícito, pero esto es solo una preferencia. Tengo una tendencia a tratar de evitar condiciones negativas en mi código. No soy un gran admirador de buscar! Foo o false == foo y siento que más es el equivalente condicional de un negativo.
en lugar de ...
El bloque de código anterior me parece un poco más fácil de leer. Me parece más natural tener una especie de paranoia escéptica sobre mi código. Establecer un valor predeterminado independientemente de cualquier condición me hace sentir cómodo: P
fuente
Yo diría que el uso de la lógica de ramificación de cualquier tipo debe evitarse en la mayor medida posible. Si bien no hay nada malo con ELSE o IF, hay muchas formas de escribir código para minimizar la necesidad de usar cualquier lógica de ramificación. No digo que la lógica de ramificación se pueda eliminar por completo, será necesaria en algunos lugares, pero es posible refactorizar el código para eliminar una buena parte de él. En la mayoría de los casos, esto mejorará la inteligibilidad y precisión de su código.
Como ejemplo, los operadores ternarios también suelen ser buenos candidatos:
Usando un enfoque ternario:
Los operadores ternarios desplazan la ramificación a la derecha de una buena manera.
fuente