2010-10-14 11 views
10

Estoy buscando implementar mi propio conjunto de Exceptions para proyectos en los que estoy trabajando actualmente. El proyecto se basa en un marco central con una excepción de marco base MyFrameworkException (también estoy escribiendo este marco).Excepciones personalizadas: diferenciar a través de muchas subclases o clases individuales respaldadas con enum?

Para cualquier proyecto dado me gustaría arrojar varios tipos diferentes de Exceptions y no puedo decidir entre el uso de múltiples subclases o una sola subclase con algún tipo de Enum como parámetro de constructor.

En ambos casos he:

public class MyFrameworkException extends Exception    { /*...*/ } 

Opción 1:

public class MyProjectBaseException extends MyFrameworkException { /*...*/ } 
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ } 
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ } 
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ } 

Luego, durante todo el proyecto que lanzaba la excepción específica para cualquier problema que se produce.

Opción 2:

public class MyProjectException extends MyFrameworkException { 
    public static enum Type { 
    SpecificType1, SpecificType2, SpecificType3 
    } 
    public MyProjectException(Type type) { /*...*/ } 
} 

Aquí siempre me tiraría MyProjectException con el tipo de enumeración específica para cualquier problema que se produce. Proporcionaría algún mecanismo para que se pueda realizar una instrucción switch en cualquier MyProjectException según el tipo enum.

¿Cuál es la mejor manera de manejar excepciones en proyectos, especialmente aquellos que comparten una infraestructura común? ¿Las dos opciones anteriores son buenas soluciones? ¿Por qué o por qué no? Y cuales son las mejores soluciones?

Respuesta

6

La principal desventaja de la Opción 2 (una excepción común + enumeración) es que se pierde parte de la utilidad de las excepciones comprobadas. Un método más o menos tiene que decir simplemente "algo marco relacionada podría ir mal":

public void foo() 
throws MyFrameworkException 

... en lugar de "X o Y pueden ir mal":

public void foo() 
throws SomethingWentWrongException, SomethingElseWentWrongException 

Significa una función que necesita manejar una excepción de marco debe estar preparado para manejar cualquier de ellos, mientras que si usted es específico, una función solo necesita estar preparado para manejar las excepciones lanzadas por los métodos de marco que llama.

Para mí, una jerarquía como la Opción 1 (no necesita ser tan plana, si la estructura se sugiere a sí misma) es el camino a seguir. Dicho esto, hay personas a las que no les gustan las excepciones comprobadas, y sospecho que lo anterior no es un argumento convincente. :-)

Editar Y retomando el argumento de duffymo: Supuse que hablabas de excepciones que realmente tenías que crear. Absolutamente lanzar estándar excepciones donde sea que tenga sentido (que es casi en todas partes). No cree su propio MyFrameworkIllegalArgumentException, por ejemplo, simplemente use IllegalArgumentException (o sus diversas subclases).

+0

Para agregar a esto: La opción 2 parece códigos de error disfrazados de excepciones. –

+0

Sí, el plan es nunca volver a lanzar excepciones en nuevas excepciones envueltas y también permitir que ciertas excepciones java/third-party-lib se propaguen fuera de los métodos de mi proyecto. Muchos de mis métodos lanzarán excepciones personalizadas + otras excepciones java. – Andy

+0

@Andy: Excelente, sí, pensé que probablemente querías decir eso. –

3

Me gustaría ir con excepciones que extienden java.lang.RuntimeException con nombres de clase descriptivos.

Si tiene tantas excepciones específicas de negocios que esto se vuelve opresivo, significa que probablemente lo esté haciendo mal.

Consulte el consejo de Joshua Bloch sobre favoring standard exceptions.

+0

'java.lang.Runnable'? ¿Querías decir 'RuntimeException'? –

+0

Sí, lo hice. Yendo muy rápido; distraído. Gracias por la corrección. – duffymo

1

No heredaría de un genérico MyFrameworkException, siempre que no proporcione ninguna funcionalidad común a todos los proyectos. De lo contrario, siempre extienda Exception.

Normalmente debería arrojar excepciones significativas en los límites de dominio/capa. Entonces, con respecto a su pregunta, debe ir con la opción 1, teniendo en cuenta el punto anterior. La opción 2 aumentaría la complejidad del código, ya que siempre deberá verificar el tipo de excepción para determinar qué fue lo que salió mal. Deje que la clase de excepción hable por sí misma.

+0

MyFrameworkException tendría algunas funciones básicas y me permitiría identificar/agrupar las excepciones que se originan en todo el paquete de código, por lo que todavía quiero usarlo como base. – Andy

+0

Estoy de acuerdo con Andy: veo muy poco o ningún motivo para extender algo más que las clases base de java.lang. – duffymo

Cuestiones relacionadas