2009-06-10 10 views
5

Je voudrais obtenir un deuxième avis sur la façon de gérer les exceptions dans les "événements" (entrée de touche, mise à jour de l'écran, etc.). Dans ce cas, j'ai le contrôle sur l'expéditeur de l'événement.Java Gestion des exceptions dans les "événements"

Ainsi, un module est réglé pour gérer un événement (il implémente une interface d'écoute, et est inscrit contre un émetteur d'événement):

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

L'expéditeur de l'événement est tout simplement:

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

Alors si/quand quelque chose ne va pas dans le récepteur:

  • Dois-je essayer de faire face à l'exception de la re, et ne jamais jeter quelque chose à l'expéditeur? Parfois, les auditeurs n'ont pas le "contexte" pour gérer correctement une erreur, n'est-ce pas?

  • Est-il mal vu de renvoyer une exception à un module d'envoi d'événement, pour qu'il soit traité de manière documentée? par exemple. "Lancer une IOException entraînera une réinitialisation ..". Cela semble non standard des javadocs que j'ai lus. Dois-je simplement me connecter et ignorer l'exception en cas de problème & Rien ne peut être fait à ce sujet?

Répondre

6

La convention Java est que les méthodes d'écoute ne lancent pas d'exceptions. Évidemment, les erreurs de programmation peuvent faire en sorte qu'un écouteur lance une exception RuntimeException, mais la source de l'événement ne peut en aucun cas récupérer, car il aura laissé les objets du programme dans un état inconnu, peut-être inconsistant.

Il appartient donc à l'utilisateur d'intercepter les exceptions vérifiées et d'en récupérer (annuler une transaction, par exemple) ou de les signaler à un autre objet. J'utilise souvent une interface ErrorHandler qui ressemble à:

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

Un écouteur d'événement indique son ErrorHandler sur les erreurs qui se sont produites.

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); 
     } 
    }   
} 

I écouteurs d'événements initialiser avec une mise en œuvre de ce qui gère l'échec de quelque manière logique à ce moment-là dans l'application. Il peut apparaître une boîte de dialogue, afficher une icône d'erreur clignotante dans la barre d'état, enregistrer un message d'audit ou annuler le processus, par exemple.

+0

Architecture intéressante et réponse utile, merci! Je suppose que mon problème est que les écouteurs ne sont pas toujours prêts à afficher des choses, ou à fournir des commentaires utilisateurs, en utilisant des événements biaisant l'analogie de la pile descendante qui rend les exceptions si puissantes (gérer l'exception à un point approprié de la pile) , où quelque chose peut être fait). De toute façon je pense que les auditeurs devront faire face à l'erreur, d'une manière ou d'une autre. –

+0

Vous devez concevoir le système pour que les auditeurs puissent gérer l'erreur. Une exception déroulera la pile à l'écouteur. L'écouteur a été appelé par quelque chose qui ne sait pas comment réagir à l'exception - un bouton appelé sur le thread de distribution d'événement Swing, ou le thread de remise de message d'un fournisseur JMS, par exemple. Vous devez instancier l'écouteur à un endroit et à un moment où vous pouvez lui donner tout le contexte dont il a besoin pour réagir à l'exception de manière sensée. – Nat

1

Lorsque rien ne peut être fait, vous devez vous connecter et envoyer un message à l'utilisateur. Si quelque chose se passe mal qui peut endommager les données ou donner des résultats erronés si vous ne pouvez pas récupérer, vous devez fermer l'application.

0

L'approche habituelle consiste à ignorer le problème. Les auditeurs ne devraient pas lancer d'exceptions non contrôlées.

Une meilleure approche serait d'attraper et de consigner RuntimeException s. Ceux-ci indiquent généralement une erreur de programmation. Si un widget sur l'écran lance un NPE, il n'y a aucune raison pour que le reste de la fenêtre ne finisse pas de peindre. L'utilisateur peut alors sauvegarder ses données et redémarrer ou contourner le problème. Dans le cas de Error s, cela signifie généralement qu'il y a une situation grave, telle que OutOfMemeory et que l'attrapage se traduira par un débordement. Personne ne dérange en faisant cela.

+0

"il n'y a aucune raison pour que le reste de la fenêtre ne finisse pas de peindre" - c'est sûr; le widget manquant pourrait très bien être critique, et le reste de la fenêtre pourrait alors être inutile. En fait, il pourrait être inutile et sembler faire quelque chose, ce qui est une expérience utilisateur pire que de s'écraser simplement. Si le programmeur ne s'attendait pas à un état particulier, vous devez supposer que l'état est juste cassé. – cdhabecker