algorithm - tag - flujos de excepcion casos de uso
Excepciones para el flujo de control (7)
¿Por qué no solo devuelve el valor resultante? Si devuelve algo, suponga que es exitoso. Si no puede devolver un valor, significa que el ciclo falló.
Si debe regresar de una falla, le recomendaría que haga una excepción.
Hay una publicación interesante aquí acerca de esto, en relación con el flujo de control de aplicación cruzada.
Bueno, recientemente, me encontré con un problema interesante. Generando el enésimo valor en una secuencia recursiva potencialmente (prácticamente) interminable. Este algoritmo en particular estará en al menos 10-15 referencias de pila en el punto en que tenga éxito. Mi primer pensamiento fue arrojar una SuccessException que se parecía a esto (C #):
class SuccessException : Exception
{
public string Value
{ get; set; }
public SuccessException(string value)
: base()
{
Value = value;
}
}
Entonces haz algo como esto:
try
{
Walk_r(tree);
}
catch (SuccessException ex)
{
result = ex.Value;
}
Entonces mis pensamientos volvieron aquí, donde he escuchado una y otra vez que nunca utilizo Excepciones para el control de flujo. ¿Alguna vez hay una excusa? ¿Y cómo estructuraría algo como esto, si lo implementara?
El problema con el uso de excepciones es que tey (en el gran esquema de cosas) son muy ineficientes y lentos. Seguramente sería tan fácil tener una condición if dentro de la función recursiva para simplemente regresar cuando sea necesario. Para ser honesto, con la cantidad de memoria en PCs modernas es poco probable (aunque no imposible) que obtendrás un desbordamiento de pila con solo un pequeño número de llamadas recursivas (<100).
Si la pila es un problema real, podría ser necesario ser ''creativo'' e implementar una ''estrategia de búsqueda limitada en profundidad'', permitir que la función regrese de la recursión y reiniciar la búsqueda desde el último nodo (el más profundo).
En resumen: las excepciones solo deben usarse en circunstancias excepcionales; el éxito de una llamada a función no creo que califique como tal.
En este caso, estaría mirando su método Walk_r, debería tener algo que devuelva un valor, arrojar una excepción para indicar el éxito, NO es una práctica común, y como mínimo va a ser MUY confuso para cualquiera que vea el código. Por no mencionar la sobrecarga asociada a las excepciones.
No es una buena idea lanzar excepciones como parte de un algoritmo, especialmente en .net. En algunos idiomas / plataformas, las excepciones son bastante eficientes cuando se lanzan, y generalmente lo son, cuando un iterable se agota, por ejemplo.
Usar excepciones en el flujo normal de programas en mi libro es una de las peores prácticas de la historia. Considere la pobre savia que está buscando excepciones tragadas y está ejecutando un depurador configurado para detener cada vez que ocurre una excepción. Ese tipo ahora se está enojando ... y tiene un hacha. :PAG
Voy a hacer de abogado del diablo aquí y me quedo con la excepción para indicar el éxito. Puede ser costoso arrojar / atrapar pero eso puede ser insignificante comparado con el costo de la búsqueda en sí mismo y posiblemente menos confuso que una salida temprana del método.
walk_r simplemente debe devolver el valor cuando se golpea. Es un ejemplo de recursión bastante estándar. El único problema potencial que veo es que dijiste que es potencialmente interminable, que tendrá que ser compensado en el código walk_r manteniendo el recuento de la profundidad de recursión y deteniéndose en algún valor máximo.
La excepción realmente hace que la codificación sea muy extraña ya que la llamada al método arroja ahora una excepción para devolver el valor, en lugar de simplemente devolver ''normalmente''.
try
{
Walk_r(tree);
}
catch (SuccessException ex)
{
result = ex.Value;
}
se convierte
result = Walk_r(tree);