Sé que esto puede ser muy específico para el caso de uso, pero me pregunto con demasiada frecuencia. ¿Existe una sintaxis generalmente preferida?
No estoy preguntando cuál es el mejor enfoque cuando estoy en una función, estoy preguntando si debo salir temprano o simplemente no llamar a la función.
Ajustar si alrededor de la llamada de función
if (shouldThisRun) {
runFunction();
}
Tener if ( guardia ) en función
runFunction() {
if (!shouldThisRun) return;
}
La última opción obviamente tiene el potencial de reducir la duplicación de código si esta función se llama varias veces, pero a veces se siente mal agregarla aquí, ya que puede estar perdiendo la responsabilidad única de la función.
Heres un ejemplo
Si tengo una función updateStatus () que simplemente actualiza el estado de algo. Solo quiero que se actualice el estado si el estado ha cambiado. Sé los lugares en mi código donde el estado tiene el potencial de cambiar, y sé otros lugares donde definitivamente ha cambiado.
No estoy seguro de si soy solo yo, pero me parece un poco sucio comprobar esta función interna, ya que quiero mantener esta función lo más pura posible; si la llamo, espero que se actualice el estado. Pero no puedo decir si es mejor terminar la llamada en un cheque en los pocos lugares donde sé que tiene el potencial de no haber cambiado.
fuente
Respuestas:
Ajustar un if alrededor de una llamada de función:
Esto es para decidir si la función debe llamarse en absoluto, y es parte del proceso de toma de decisiones de su programa.
Cláusula
de protección en función (retorno temprano): Esto es para proteger contra ser llamado con parámetros inválidos
Una cláusula de protección utilizada de esta manera mantiene la función "pura" (su término). Solo existe para garantizar que la función no se rompa con datos de entrada erróneos.
La lógica sobre si llamar a la función es un nivel más alto de abstracción, incluso si solo es así. Debería existir fuera de la función misma. Como dice DocBrown, puede tener una función intermedia que realice esta verificación, para simplificar el código.
Esta es una buena pregunta, y se enmarca dentro del conjunto de preguntas que conducen al reconocimiento de los niveles de abstracción. Cada función debe operar en un solo nivel de abstracción, y tener tanto la lógica del programa como la lógica de la función en la función se siente mal para usted, esto se debe a que están en diferentes niveles de abstracción. La función en sí es un nivel inferior.
Al mantenerlos separados, se asegura de que su código sea más fácil de escribir, leer y mantener.
fuente
Puede tener ambas: una función que no verifica los parámetros y otra que sí, de esta manera (tal vez devolviendo información sobre si se realizó la llamada):
De esa manera, puede evitar la lógica duplicada al proporcionar una función reutilizable
tryRunFunction
y aún tener su función original (tal vez pura) que no realiza la verificación en el interior.Tenga en cuenta que a veces necesitará una función como
tryRunFunction
con un cheque integrado exclusivamente, por lo que puede integrar el cheque enrunFunction
. O no tiene necesidad de volver a usar el cheque en ningún lugar de su programa, en cuyo caso puede dejarlo en la función de llamada.Sin embargo, trate de hacer que sea transparente para la persona que llama lo que sucede dando a sus funciones nombres propios. Por lo tanto, las personas que llaman no tienen que adivinar o analizar la implementación si tienen que hacer las comprobaciones por sí mismos, o si la función llamada ya lo hace por ellos. Un prefijo simple como a
try
menudo puede ser suficiente para esto.fuente
runFunction
. Una función comoupdateStatus()
puede ir acompañada de otra función comoupdateIfStatusHasChanged()
. Pero esto es 100% dependiente de los casos, no hay una solución "única para todos", así que sí, estoy de acuerdo, el idioma "intentar" no siempre es una buena opción.En cuanto a quién decide si ejecutar, la respuesta es, de GRASP , quién es el "experto en información" que sabe.
Una vez que haya decidido eso, considere cambiar el nombre de la función para mayor claridad.
Algo como esto, si la función decide:
O, si se supone que la persona que llama debe decidir:
fuente
Me gustaría ampliar la respuesta de @ Baldrickk.
No hay una respuesta general a su pregunta. Depende del significado (contrato) de la función a llamar y la naturaleza de la condición.
Analicemoslo en el contexto de su llamada de ejemplo
updateStatus()
. Su contrato probablemente sea actualizar algún estado porque ha sucedido algo que influye en el estado. Esperaría que se permitan las llamadas a ese método incluso si no hay un cambio de estado real, y que sea necesario si hay un cambio real.Por lo tanto, un sitio de llamadas puede omitir una llamada
updateStatus()
si sabe que (dentro de su horizonte de dominio) nada relevante ha cambiado. Esas son las situaciones en las que la llamada debe estar rodeada por unaif
construcción apropiada .Dentro de la
updateStatus()
función, puede haber situaciones en las que esta función detecta (a partir de datos dentro de su horizonte de dominio) que no hay nada que hacer, y ahí es donde debería regresar antes.Entonces, las preguntas son:
Con una
updateStatus()
función, esperaría ver ambas cosas: llamar a sitios que no saben que nada ha cambiado, omitir la llamada y verificar la implementación de las situaciones de "nada cambiado" antes, incluso si de esta forma la misma condición se verifica dos veces, ambas dentro y fuera.fuente
Hay muchas buenas explicaciones. Pero quiero parecer inusual: suponga que lo usa de esta manera:
Y necesita llamar a otra función en un
runFunction
método como este:¿Qué harás? ¿Copias todas las validaciones de arriba a abajo?
No lo creo. Por lo tanto, generalmente hago el mismo enfoque: validar entradas y verificar condiciones en el
public
método. Los métodos públicos deben hacer sus propias validaciones y verificar las condiciones requeridas, incluso las personas que llaman lo hacen. Pero deje que los métodos privados solo hagan su propio negocio . Alguna otra función puede llamarrunFunction
sin hacer ninguna validación o verificar ninguna condición.fuente