2010-04-29 13 views
5

Digamos que tengo el siguiente interfaz Java que Puede que no modificar:La interfaz de Java no declara ninguna excepción. ¿Cómo administrar las excepciones marcadas de la implementación?

public interface MyInterface { 
    public void doSomething(); 
} 

Y ahora la clase que implementa es la siguiente:

class MyImplementation implements MyInterface { 
    public void doSomething() { 
    try { 
     // read file 
    } catch (IOException e) { 
     // what to do? 
    } 
    } 
} 

no puedo recuperarse de no leer el archivo.

Una subclase de RuntimeException claramente me puede ayudar, pero no estoy seguro de si es lo correcto: el problema es que esa excepción no estaría documentada en la clase y un usuario de la clase posiblemente obtendría esa excepción y no sabes nada de resolver esto.

¿Qué puedo hacer?


Todos estamos de acuerdo: la interfaz es defectuosa.

solución I eligió

finalmente me decidí a escribir una MyVeryOwnInterface que se extiende MyInterface y agrega como parte de la firma de los métodos defectuosos del MyRuntimeException:

public interface MyVeryOwnInterface extends MyInterface { 
    public void doSomething() throws MyRuntimeException; 
} 
class MyImplementation implements MyVeryOwnInterface { 
    public void doSomething() throws MyRuntimeException { 
    try { 
     // read file 
    } catch (IOException e) { 
     throw new MyRuntimeException("Could not read the file", e); 
    } 
    } 
} 
+0

Ver: http://www.javapractices.com/topic/TopicAction.do?Id=44 –

Respuesta

8

Ha encontrado el problema leaky abstractions. No hay una solución realmente buena, y usar un RuntimeException es prácticamente lo único que puede hacer.

Posiblemente, este es también un ejemplo de por qué las excepciones comprobadas son un concepto fallido.

+0

O es un ejemplo de por qué "doSomething" tiene demasiadas responsabilidades. – CPerkins

+2

Ok, gracias por el principio de abstracciones con fugas. Sin embargo, es la primera vez en 10 años de experiencia en Java que encuentro este problema, no es lo que yo llamaría un "concepto fallido". –

+6

Por supuesto, las excepciones comprobadas no son un "concepto fallido". Ellos son extremadamente útiles. En este caso, la falla es con el diseñador de la interfaz, no con el diseñador del lenguaje. – DJClayworth

0

Yo no creo que haya es cualquier cosa hacer excepto para declarar throws IOException en la interfaz. Esa es simplemente la naturaleza de las interfaces Java y las excepciones marcadas.

Puede tener otro método en su clase (doSomethingDangerous) que arroja el IOException. Desde el doSomething -implementación, simplemente llame a doSomethingDangerous (envuelto en un try/catch) y luego, donde quiera que desee tener cuidado con doingSomething llame al doSomethingDangerous directamente.

2

Si no puede recuperar lo que necesita tirar y, por lo tanto, envolverlo en una RuntimeException o un Error y lanzar eso.

public class Unchecked extends Error { 

    private final Exception source; 

    public Unchecked(Exception source) { 
     this.source = source; 
    } 

    public String toString() { 
     return "Unchecked Exception, Caused by: " + source; 
    } 

    public Exception getSource() { 
     return source; 
    } 

    public static Unchecked wrap(Exception cause) { 
     return new Unchecked(cause); 
    } 
} 
0

sugeriría

throw new RuntimeException("while reading file " + fileName + "...", e); 

no es el problema aquí, que la interfaz no espera ningún problema en absoluto?

(y es posible que desee crear su propia OurCompanyDomainException extiende RuntimeException para que sea fácil de distinguir en el código en el otro lado de la interfaz).

1

Claramente, el diseñador de la interfaz tiene la culpa de no considerar la posibilidad de que doSomething() pueda fallar. Idealmente, debería haber permitido que se lanzara IOException (si sospechaba que IO sería invocado) o una SomethingException (marcada) que podría usar para envolver su IOException.

Si el diseñador de interfaz está disponible para usted, hable con él y pregúntele qué esperaba que ocurriera en caso de error. Tal vez puedan cambiar la interfaz: o tal vez sea aceptable fallar silenciosamente de acuerdo con el contrato de la interfaz.

Al fallar todos estos, se ve reducido a una opción de falla silenciosa (posiblemente grabando pero no respondiendo al problema) o lanzando una RuntimeException que puede terminar el proceso.

Cuestiones relacionadas