2010-04-29 7 views
5

Diciamo che ho il seguente interfaccia Java che non potrà modificare:L'interfaccia Java non dichiara alcuna eccezione. Come gestire le eccezioni controllate dell'implementazione?

public interface MyInterface { 
    public void doSomething(); 
} 

E ora la classe che implementa è come questo:

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

non riesco a recuperare da non leggere il file.

Una sottoclasse di RuntimeException può chiaramente aiutarmi, ma non sono sicuro se sia la cosa giusta da fare: il problema è che quell'eccezione non sarebbe quindi documentata nella classe e un utente della classe potrebbe ottenere quell'eccezione non sa nulla su come risolvere questo.

Cosa posso fare?


Siamo tutti d'accordo: l'interfaccia è difettosa.

Soluzione ho scelto

alla fine ho deciso di scrivere un MyVeryOwnInterface che si estende MyInterface e aggiunge come parte della firma dei metodi difettosi 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

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

risposta

8

Hai riscontrato il problema di leaky abstractions. Non esiste una soluzione davvero buona e l'utilizzo di una RuntimeException è praticamente l'unica cosa che puoi fare.

Probabilmente, questo è anche un esempio del perché le eccezioni controllate sono un concetto fallito.

+0

Oppure è un esempio del perché "doSomething" ha troppe responsabilità. – CPerkins

+2

Ok, grazie per il principio delle astrazioni che perdono. Tuttavia, è la prima volta in 10 anni di esperienza in Java che incontro questo problema, che non è quello che definirei un "concetto fallito". –

+6

Ovviamente le eccezioni controllate non sono un "concetto fallito". Sono estremamente utili. In questo caso l'errore è con il progettista dell'interfaccia, non con il progettista del linguaggio. – DJClayworth

0

Io non credo che ci è tutto da fare tranne che per dichiarare throws IOException nell'interfaccia. Questa è semplicemente la natura delle interfacce Java e delle eccezioni controllate.

Si potrebbe avere un altro metodo nella classe (doSomethingDangerous) che genera IOException. Dall'implementazione doSomething, è sufficiente chiamare doSomethingDangerous (racchiuso tra un try/catch) e quindi, se mai si desidera prestare attenzione a doingSomething, si chiama direttamente doSomethingDangerous.

2

Se non è possibile recuperare di quanto è necessario gettare e quindi avvolgerlo in un RuntimeException o un errore e lanciarlo.

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

vorrei suggerire

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

non è il problema qui, che l'interfaccia non si aspetta problemi a tutti?

(e si potrebbe voler creare il proprio OurCompanyDomainException estende RuntimeException per semplificare la distinzione nel codice sull'altro lato dell'interfaccia).

1

Chiaramente il progettista di interfacce è in errore per non considerare la possibilità che doSomething() possa non riuscire. Idealmente, avrebbe dovuto consentire a IOException di essere lanciato (se sospettava che l'I/O sarebbe stato sottoposto a invezione) o a SomethingException (controllato), che potevi utilizzare per avvolgere la tua IOException.

Se il progettista dell'interfaccia è disponibile, parlare con loro e chiedere cosa si aspettavano che accadesse in caso di errore. Forse possono cambiare l'interfaccia: o forse è accettabile fallire silenziosamente in base al contratto dell'interfaccia.

In caso contrario, si è ridotto a una scelta di errore in modalità non presidiata (probabilmente la registrazione ma non risposta al problema) o il lancio di una RuntimeException che può interrompere il processo.

Problemi correlati