2010-07-27 9 views
10

Me di cuenta de que nunca he visto una sola jerarquía de excepciones para la cual crear subclases pero capturar la clase principal era realmente útil (excepto, por supuesto, para la clase base Excepción, que tiene derivado).¿Las jerarquías de excepción son realmente útiles?

¿Las jerarquías de excepciones son realmente útiles, x o todas las excepciones deben derivarse de la clase de excepción base del lenguaje?

+0

+1 para usar xor en una oración ordinaria (y para hacer una buena pregunta)! – apollodude217

+0

¿Olvidaste un * no * en tu comentario de corchete? – Wolf

+0

Tan nervioso, @Wolf. – zneak

Respuesta

5

Las jerarquías de excepciones son útiles para agrupar excepciones relacionadas entre sí, cuando se necesita una granularidad diferente de la captura en diferentes lugares.

Poner todas las excepciones de la aplicación en un solo lugar es el caso de uso más común. Esto le permite capturar MyAppException en cualquier momento que desee atrapar todos los errores que provienen de su aplicación, pero aún captura excepciones más específicas cuando corresponda. (En .NET, la clase ApplicationException estaba destinado para esto, pero ha sido desaprobado por varias razones.)

Pero También puede agrupar juntos excepciones en los límites del módulo, o en cualquier otra forma que tenga sentido. Use FooModuleException para excepciones provenientes del módulo Foo, pero capture y maneje FooModuleMustFrobnicate especialmente interno a Foo. O cualquier situación equivalente.

He utilizado todos estos patrones en diferentes momentos.

+3

¿Tiene un ejemplo donde capturar excepciones en una granularidad diferente es realmente útil? Quiero decir, si olvidamos toda la teoría y somos prácticos, nunca he visto un lugar donde la granularidad de las capturas haya sido utilizada. Por otro lado, he visto a muchas personas atrapar 'IOException' cuando abren un archivo, y sin embargo, todo lo que pueden obtener es' FileNotFoundException'. Usan 'IOException' porque la jerarquía les hace pensar que algo más podría suceder mientras que, de hecho, las subclases' IOException' son bastante inconexas en términos de contextos de apariencia. – zneak

1

Nunca he creado una única jerarquía de excepciones para toda la aplicación, porque una excepción en general puede aportar una semántica diferente y, por lo tanto, debe manejarse de manera diferente.

Algunas excepciones informan sobre fallas del sistema, otras excepciones informan sobre errores, y algunas otras, sobre alguna condición excepcional, que se pueden recuperar correctamente en un nivel superior.

Para esta jerarquía de excepciones de excepciones "lógica de negocios" puede ayudarle a no violar el principio de apertura abierta al anular algunos métodos en descendientes.

Considere siguiente ejemplo:

public abstract class Base 
{ 
    /// Perform some business-logic operation 
    /// and throw BaseFooException in certain circumstances 
    public abstract void Foo(); 
} 

public class Derived1 : Base 
{ 
    /// Perform some business-logic operation 
    /// and throw DerivedFooException in certain circumstances. 
    /// But caller could catch only BaseFooException 
    public abstract void Foo() {} 
} 

class BaseFooException : Exception {} 

class DerivedFooException : BaseFooException {} 

jerarquía de excepciones puede ser útil en el marco de la costumbre o en las bibliotecas específicas, pero en el caso general (en aplicaciones de negocios) no creo que la creación de una jerarquía de excepciones profunda y amplia es una buena idea.

1

TL; DR

  1. jerarquías de excepción son inútil para la captura de excepciones (excepto para la diferenciación de base por cierto errores no recuperables del sistema (Java Error) y excepciones "normales" en tiempo de ejecución La noción.. que "necesita una granularidad diferente para atrapar en diferentes lugares" es IMHO fundamentalmente defectuoso. (Excepto, para reiterar, para diferenciar entre excepciones y aserciones y otras cosas irrecuperables para todo el sistema.)
  2. Las jerarquías de excepciones pequeñas tienen sentido en los idiomas actuales como un medio de construyendo diferentes errores con la mayor cantidad de información posible.

Estoy llegando lentamente a considerar todo el concepto de arbitrariamente mecanografiadas excepciones, como los veo implementados y supone-a-ser-usada en C++, C# y Java como totalmente inútil.

El problema no es tanto la jerarquía de excepciones per se, sino que cuando escribo código y excepción son excepcional, que no me importa qué tipo de excepción fue arrojado a los efectos de la captura de él.

En toda mi codificación en C++, Java y C#, encontré - las excepciones excepcionales, que no fueron mal utilizados para el flujo de control - no un caso en el que quería para filtrar (es decir, la captura o no coger) las excepciones por su tipo "jerárquico". Es decir, hay casos excepcionales en que una función arroja 3 excepciones diferentes, y quiero manejar específicamente una de ellas, y manejar las otras dos como "error" general (como se describe a continuación) pero nunca he encontrado esto en un caso donde la jerarquía de excepciones fue útil porque pude agrupar de manera significativa los dos casos por clases base.

Si cualquier operación (en la que me importa) en mi programa falla con cualquier excepción, estas operaciones se considera fracasado, y:

  • consigo lo información que pueda de objeto atrapado
  • continuar con el manejo de errores contextualizada (re-lanzamiento, error de visualización, registro, volver a intentar, recuperar , etc.)

Creo que Java es el único de la tres idiomas que al menos tiene el enfoque correcto con su jerarquía, a saber:

  • Throwable no se utilizan en el código de usuario
  • Error las cosas que no quieren ponerse al día - sólo volcado de memoria
  • Exception - para todo las cosas que básicamente siempre se desea capturar (a excepción de cuando se estropeó una interfaz y utiliza una excepción cuando realmente no debería)

//

La jerarquía de <stdexcept> C++ 's tiene el enfoque básico derecho en la diferenciación entre logic_error - básicamente afirmaciones - y runtime_error - cosas que se acaba de forma inesperada falló. (Las subclases de tesis son en gran medida irrelevantes cuando captura.)

Excepto, por supuesto que too much cosas deriva directamente de std::exception por lo que no puede hacer uso de la diferenciación proporcionada por el tiempo de ejecución y el error lógico. (Y, por supuesto, cualquier código es libre de arrojar lo que quieran, por lo que es muy probable que haya un montón de clases derivadas de logic_error que realmente deberían ser runtime_errors y viceversa.


Para citar otra respuesta:

Exception hierarchies are useful for grouping related exceptions together, when you need different granularity of catching in different places.

pero en mi experiencia nuncaquieren "ponerse en diferentes lugares", porque simplemente no tiene sentido.

O bien quiero capturar, en cuyo caso capturo todo (cosas modulo como las Error excepciones de clase de Java) o no quiero capturar, en cuyo caso la jerarquía no es necesaria, porque no hay trampa.


Tome opening and reading from a file:

Si hay (sería) cualquier tipo de excepción que me importa específicamente sobre, porque puedo hacer algo al respecto ("recuperar"), entonces esto no debería ser reportado como una excepción en absoluto, porque es flujo de control normal. (Si el error es tal y tal, puedo hacer tal y tal básicamente localmente).

Si, por otro lado, no puedo hacer nada acerca de un error, pero grabo la operación de archivo como fallida, luego tener cualquier granularidad de captura es completamente inútil.

+0

Creo que en general se me ocurrieron 4 tipos de error: FATAL: Todo el sistema es un desastre. No hay forma de recuperarse USER_MANAGED_SYSTEM_ERROR: p. sin espacio en disco o red inactiva. Algo que el usuario debe corregir, entonces el sistema funcionará. El programa puede tener alguna manera de monitorear cuándo cambiará la situación, pero no debería volver a intentar nada todavía. TRANSITORIO: Sistema ocupado o lo que sea, pero vuelva a intentarlo después de una pausa o lo que sea. MALA PETICIÓN: nada malo con el sistema solo su solicitud. No lo intente nuevamente, fallará siempre pero puede continuar con otras solicitudes. – CashCow

Cuestiones relacionadas