2009-06-10 9 views
5

Vorrei ricevere un secondo parere su come gestire le eccezioni all'interno di "eventi" (inserimento chiave, aggiornamento schermo ecc.). In questo caso ho il controllo sul mittente dell'evento.Gestione delle eccezioni Java all'interno di "eventi"

Quindi un modulo è impostato per gestire un evento (che implementa un'interfaccia ascoltatore, ed è registrato nei confronti di un mittente evento):

public void DefaultSet (CardData oldDefault, CardData newDefault) 
{ 
} 

Il mittente evento è semplicemente:

 for (Enumeration e = listeners.elements(); e.hasMoreElements();) 
     { 
      RetrieverListener thisListener = (RetrieverListener) e.nextElement(); 
      thisListener.DefaultSet(oldDefault, newDefault); 
     } 

Così se/quando qualcosa va storto nel ricevitore:

  • Se dovessi provare ad affrontare l'eccezione il re, e non restituire mai nulla al mittente? A volte gli ascoltatori non hanno il "contesto" per gestire correttamente un errore, giusto?

  • È corrugato per restituire un'eccezione a un modulo di invio eventi, da gestire in modo documentato? per esempio. "Lanciare una IOException comporterà un reset ..". Questo sembra non standard dalle javadoc che ho letto.

  • Devo solo accedere e ignorare l'eccezione quando qualcosa va storto & non si può fare nulla al riguardo?

risposta

6

La convenzione Java è che i metodi di ascolto non generano eccezioni. Ovviamente, gli errori di programmazione potrebbero far sì che un listener lanci una RuntimeException, ma in nessun caso l'origine degli eventi può ripristinarla perché avrebbe lasciato gli oggetti del programma in uno stato sconosciuto, forse incoerente.

Spetta quindi all'ascoltatore rilevare le eccezioni controllate e recuperarle (ad esempio, ripristinare una transazione) o segnalarle a un altro oggetto. Io uso spesso un'interfaccia ErrorHandler che sembra qualcosa di simile:

public interface ErrorHandler { 
    public void errorOccurred(String whatIWasTryingToDo, Exception failure); 
} 

Un listener di eventi racconta la sua ErrorHandler sugli errori che si sono verificati.

public class SomeClass implements SomeKindOfListener 
    private final ErrorHandler errorHandler; 
    ... other fields ... 

    public SomeClass(ErrorHandler errorHandler, ... other parameters ...) { 
     this.errorHandler = errorHandler; 
     ... 
    } 

    public void listenerCallback(SomeEvent e) { 
     try { 
      ... do something that might fail ... 
     } 
     catch (SomeKindOfException e) { 
      errorHandler.errorOccurred("trying to wiggle the widget", e); 
     } 
    }   
} 

ho inizializzare i listener di eventi con un'implementazione di questo che si occupa il fallimento in qualunque modo un senso a quel punto l'applicazione. Potrebbe apparire una finestra di dialogo, mostrare un'icona di errore lampeggiante nella barra di stato, registrare un messaggio di controllo o interrompere il processo, ad esempio.

+0

Architettura interessante e risposta utile, grazie! Credo che il mio problema sia che gli ascoltatori non sono sempre orientati a mostrare cose, o fornire feedback da parte degli utenti, l'uso degli eventi distorce l'analogia top-down stack che rende Eccezioni così potenti (gestire l'eccezione in un punto appropriato nello stack , dove si può fare qualcosa). In ogni caso penso che gli ascoltatori dovranno affrontare l'errore, in un modo o nell'altro. –

+0

Devi progettare il sistema per rendere gli ascoltatori in grado di gestire l'errore. Un'eccezione restituirà lo stack all'ascoltatore. Il listener è stato invocato da qualcosa che non può sapere come reagire all'eccezione, ad esempio un pulsante chiamato sul thread di invio dell'evento Swing o il thread di consegna del messaggio di un provider JMS. Devi istanziare l'ascoltatore in un luogo e in un momento in cui puoi dare tutto il contesto di cui ha bisogno per reagire all'eccezione in modo ragionevole. – Nat

1

Quando non è possibile eseguire alcuna operazione, è necessario accedere e inviare un messaggio all'utente. Se qualcosa va storto che può danneggiare i dati o dare risultati errati se non puoi recuperare dovresti chiudere l'applicazione.

0

L'approccio normale è ignorare il problema. Gli ascoltatori non dovrebbero lanciare eccezioni incontrollate.

Un approccio migliore sarebbe prendere e registrare RuntimeException s. Questi generalmente indicano un errore di programmazione. Se un widget sullo schermo genera un NPE, non c'è motivo per cui il resto della finestra non debba finire di colorare. L'utente può quindi salvare i propri dati e riavviare o comunque aggirare il problema. Nel caso di Error s in genere significa che c'è una situazione grave, come ad esempio OutOfMemeory e l'acquisizione si tradurrà solo in thrashing. Nessuno si preoccupa di farlo.

+0

"non c'è motivo per cui il resto della finestra non debba finire di dipingere" - certo che c'è; il widget mancante potrebbe essere molto critico, e il resto della finestra potrebbe essere inutile. In realtà, potrebbe essere inutile e sembra che stia facendo qualcosa, che è un'esperienza utente peggiore del semplice arresto anomalo. Se il programmatore non si aspettava uno stato particolare, devi supporre che lo stato sia solo rotto. – cdhabecker