¿Cómo se hace para enseñar el manejo de excepciones a los programadores? Todas las demás cosas se enseñan fácilmente: estructuras de datos, ASP.NET, WinForms, WPF, WCF, lo que sea, todo se puede enseñar fácilmente.
Con Exception Handling, enseñarles try-catch-finally es solo la naturaleza sintáctica de Exception Handling.
Sin embargo, lo que debe enseñarse es: ¿qué parte de su código coloca en el bloque de prueba ? ¿Qué haces en el bloque de captura ?
Permítanme ilustrarlo con un ejemplo.
Está trabajando en un proyecto de formularios Windows Forms (una pequeña utilidad) y lo ha diseñado de la siguiente manera con 3 proyectos diferentes.
- UILayer
- BusinessLayer
- DataLayer
Si se produce una excepción (digamos que cargar un XDocument arroja una excepción) en DataLayer (el UILayer llama a BusinessLayer, que a su vez llama al DataLayer), ¿simplemente hace lo siguiente?
//In DataLayer
try {
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(Exception ex)
{
throw ex;
}
que se arroja nuevamente en BusinessLayer y que se captura en UILayer donde lo escribo en el archivo de registro?
¿Es así como se maneja la gestión de excepciones?
Respuestas:
Para explicar el manejo de excepciones, explique el concepto detrás de esto: el código donde ocurre un error con frecuencia no sabe cómo manejar ese error adecuadamente. El código que sabe cómo manejarlo correctamente podría ser la función que lo llamó, o podría estar más arriba en la pila de llamadas.
Cuando escribe una rutina que llama a una rutina que podría generar una excepción, si sabe cómo manejar ese error correctamente, coloque la llamada en un bloque try y coloque el código de manejo de errores en el bloque catch. Si no, déjelo solo y deje que algo sobre usted en la pila de llamadas maneje el error.
Decir "atrapar ex, tirar ex" no es una buena forma de manejar excepciones, ya que en realidad no maneja nada. Además, dependiendo de cómo funcione el modelo de excepción en su idioma, eso puede ser dañino si borra la información de seguimiento de la pila que podría haber utilizado para depurar el problema. Simplemente deje que la excepción se propague por la pila de llamadas hasta que llegue a una rutina que sepa cómo manejarla.
fuente
Como la mayoría de las cosas, las excepciones y el manejo de excepciones probablemente parecerán una solución en busca de un problema para los nuevos programadores hasta que demuestre por qué la solución aparentemente más simple (códigos de retorno de estilo C y errno) funciona tan mal. Comenzaría por motivar el problema y ponerlo en contexto. Muestra cómo se puede manejar el error usando códigos de retorno o variables globales / estáticas. Luego, dé ejemplos de por qué no funciona bien. Luego, y solo entonces, introduzca excepciones y explique que son una forma de señalización fuera de banda y que el punto principal es que el comportamiento predeterminado si ignora una excepción es pasar el dinero a la pila de llamadas a alguien que pueda manejarlo
En pocas palabras: mostrar cómo se realizó el manejo de errores en C hará que los estudiantes comprendan para qué son realmente las excepciones y por qué detectar excepciones que realmente no se pueden manejar es básicamente simular la forma en que se hicieron las cosas en la Edad Media.
fuente
Comenzaría con las Pautas de diseño para excepciones, que son cortas e incluyen DO, DO NOT y EVOID. También da las razones por qué.
En su caso de ejemplo, la sección revelvent sería Envolviendo excepciones
Y esperaría que se escribiera de esta manera. Tenga en cuenta que detecta una excepción específica e intenta agregar información para que se propague un mensaje más significativo. También tenga en cuenta que la excepción interna todavía se mantiene para fines de registro
ACTUALIZACIÓN Kanini pregunta si es correcto tener este bloque de excepción en la capa de datos o si la comprobación del archivo está disponible para la capa empresarial.
Bueno, primero me gustaría señalar que la justificación de las excepciones de envoltura es esta
Entonces, si cree que una capa superior debe saber sobre el archivo, su capa de datos debería verse así
No intente sin captura.
Personalmente, creo que a menos que su capa de datos pueda hacer algo útil, como usar un sistema predeterminado.sml que es un recurso de ensamblaje, no hacer nada o envolver la excepción es una buena apuesta, ya que su registro le dirá qué método y qué archivo fue el problema. (
throw ex
en este caso o el preferidothrow
también, pero no agrega valor). Esto significa que una vez identificado, podrá solucionar el problema rápidamente.Como ayuda, este ejemplo en particular también tiene el siguiente problema, ya que XDocument.Load puede arrojar cuatro excepciones.
No podemos garantizar con seguridad que el siguiente código no se lanzará y FileNotFoundException, simplemente porque podría estar allí cuando verificamos la existencia y desaparecer cuando cargamos. Tener eso disponible para la capa empresarial no ayudaría.
SecurityException es aún peor porque, entre otras razones, si esto se produce si otro proceso agarra tiene un bloqueo de archivo exclusivo, no obtendrá el error hasta que intente abrirlo para leerlo porque no hay un método File.CanIOpenThis (). Y si existiera tal método, todavía tiene el mismo problema que con File.Exists
fuente
Hagamos un juego de roles. (esto no es una publicación de broma)
Debería hacer un taller donde representa la cadena de llamadas. Cada persona es un objeto. Necesitarás algunos novatos y algunas personas que entiendan que el "juego" ayuda.
Use un problema realmente simple como el archivo IO. gui-> model-> file_io
La persona que es el lector de archivos necesita decirle al siguiente ...
Primero hazlo con los códigos de retorno. (¿usa notas post-it?)
si las interacciones son "lo que dice el código" muy pronto, puede hacer que las personas se den cuenta de que las excepciones son excepcionales.
para códigos de retorno, pase una nota post-it.
para excepciones, levante las manos en el aire y diga cuál es el problema.
luego pídales que hagan "atrapar x, arrojar x" y ver que, mucho peor, el diagnóstico es lo que la GUI solo obtiene "el modelo tuvo una excepción".
Creo que esto funcionará para capacitar a las personas que tienes porque las personas entienden bastante bien las interacciones con otras personas.
fuente
Me imagino que para entender las excepciones, primero debe comprender la relación niño / padre de las clases, por ejemplo. Si comprende que un niño puede heredar la funcionalidad de un padre, es posible que en un nivel primario entienda que si un niño tiene un problema que no puede resolver, pasará este problema (excepción) a su padre y dejará que el padre se ocupe con eso.
Esto se convierte en una relación encadenada hasta que terminas en un lugar donde algo sabe cómo manejar la excepción.
Y hasta donde finalmente llega, esta es la parte trivial ... cuando ocurre un problema, algo tiene que manejarlo para que el programa no salga fatalmente, después de que se maneja esa excepción, el bloque finalmente está allí, que siempre se ejecutará independientemente del intento de captura .
Un buen ejemplo de esto podría ser con las redes:
o en caso de excepción:
fuente
Entregue una Aplicación al novato que tenga muy buen manejo de Excepciones. Lanza alguna excepción en alguna parte y deja que la depuren con la ayuda de Logs. Al rastrear la propagación de la excepción, deberían poder depurarla. Haz este ejercicio 3 o 4 veces. Ahora simplemente elimine todo el manejo de Excepción del código y deje que intenten rastrear la misma excepción.
Creo que la apreciación por el código de manejo de excepciones será apreciada al instante.
fuente
En mi opinión, debe pensar que el manejo de excepciones y las declaraciones de control de flujo son básicamente lo mismo. Los usa para controlar el flujo de sus programas según la condición en la que se encuentran actualmente. La diferencia es que el manejo de excepciones solo reaccionará cuando ocurra un error (o excepción).
fuente
Probablemente no ayudaría a un nuevo programador, pero descubrí que entendía el concepto de excepciones mucho mejor una vez que comencé a usar mónadas en la programación funcional. Una mónada lo obliga a considerar cada "canal" a través del cual los datos pueden viajar dentro o fuera de un programa, ya que todo lo que hace proporciona una abstracción conveniente para "ocultar" parte de ese flujo de datos.
La idea de que una función puede tener diferentes tipos de salida, y una excepción es como un tipo de retorno de mayor prioridad de la función, es bastante clara.
Eso sí, entiendo que no es así como funcionan las excepciones en la mayoría de los idiomas (detalles de implementación), pero en un sentido abstracto, eso es lo que está sucediendo.
fuente
Finge que un mono está usando el teclado
Solía decirles a mis muchachos cuando escriben código para fingir que un mono se sentará en el teclado y usará esta aplicación.
Esto les enseñó a anticipar todo tipo de cosas:
Creo que fue la palabra de tener un mono golpeando las llaves y haciendo lo que quisiera en lugar de seguirlo muy bien lo que hizo el truco. Funcionó para mi.
fuente