Question

Quand devez-vous jeter une exception personnalisée?

par exemple. J'ai un code qui se connecte à un serveur. Le code qui se connecte au serveur renvoie une IOException quand il ne parvient pas à se connecter. Dans le cadre de la méthode qu'il appelle, cela est bien beau. Il est aussi bien dans le code réseau.

Mais comme cela ne représente pas avoir une connexion (et donc ne fonctionne pas) l'exception va tout le chemin jusqu'à l'interface utilisateur. A ce stade, un IOException est très ambigous. Quelque chose comme NoConnectionException serait mieux.

Alors, ma question est: A quel stade vous devez attraper une exception à jeter à la place une autre (sur mesure) exception mieux adaptée à l'abstraction?

Était-ce utile?

La solution

Je me attends à des exceptions à parler en termes de ce que j'ai demandé la méthode d'origine de faire. par exemple.

read -> ReadException
connect -> ConnectException
buildPortfolio -> FailedToBuildPortfolioException

etc. Ce fait abstraction ce qui se passe sous les couvertures (à savoir sont prises par vous communicantes, etc.). En règle générale, lorsque je crée une interface pour un composant, je crée souvent une exception correspondante ou un ensemble d'exceptions. Mon interface sera appelée Component, et mes exceptions sont généralement ComponentException (par exemple RateSource et RateSourceException). Il est cohérent et facile à exporter vers différents projets comme un ensemble complet de composants.

L'inconvénient est que vous créez beaucoup d'exceptions, et vous devrez peut-être effectuer beaucoup de traductions. Le côté positif est que (comme vous avez identifié), vous obtenez peu à aucune fuite d'abstraction.

À un certain moment au cours de la hiérarchie des appels de méthode (et donc des exceptions), vous pouvez décider qu'aucune récupération ne peut avoir lieu (ou il est à un endroit inapproprié) et se traduire par des exceptions non vérifiées être traitées plus tard.

Autres conseils

Je sais que cela est étiqueté comme « langue-agnostique », mais je ne pense pas que ce soit vraiment. Venant d'un point de vue C de, je pense que très peu les opérations de base de lancer une exception - la bibliothèque standard C ++ utilise uniquement des exceptions dans très peu d'endroits. Donc, mon propre code est souvent le premier lieu où des exceptions peuvent être générées. Dans ce code, j'aime une hiérarchie très plate - Je ne veux pas être déconner avec des centaines de captures () clauses plus tard dans le code, et ne l'ai jamais compris Java et obsession apparente de C # avec la création de hiérarchies baroques de classe et espace de noms <. / p>

Alors, pour mon code C ++ - un type d'exception, contenant un message d'erreur significatif, par bibliothèque. Et un pour l'exécutable final.

Je pense qu'il ya deux questions cachées ici: a) Quand doit-on cacher une exception derrière une autre exception. b) Quand doit-on utiliser une exception personnalisée pour cela.

a) Je dirais: si jamais une exception traverse la frontière de deux couches dans l'application, il devrait se cache derrière une exception qui est plus qu'appropriée pour la nouvelle couche. Exemple:. Parce que vous faites des choses à distance, vous obtenez un ConnectionWhatEverException

Mais l'appelant ne doit pas être au courant des problèmes de connexion. Comme il veut juste obtenir un service effectué, alors il obtient un ServiceOutOfOrderException. La raison en est: A l'intérieur de la couche, faisant Remoting, vous pourriez faire quelque chose avec un ConnectionException USEFULL (nouvelle tentative, écrire dans une file d'attente .. backout). Une fois que vous avez quitté cette couche, on ne sait pas comment gérer un ConnectionException. Mais ils devraient être en mesure de décider, qu'est-ce que faire, lorsque le service ne fonctionne pas.

b) Lorsqu'il n'y a pas d'exception correspondante existante. Il y a quelques exceptions utiles en Java par exemple. J'utilise IllegalState et IllegalArgument assez souvent. Un argument fort pour une nouvelle classe d'exception est, si vous avez un contexte utile de fournir. Par exemple, le nom du service qui a échoué pourrait être un argument d'un ServiceFailedException. Il suffit de ne pas créer une classe pour chaque appel de méthode, ou quoi que ce soit à cet effet. 100 classes d'exception ne sont pas un problème, tant qu'ils ont un comportement différent (à savoir au moins différents champs). Si elles ne diffèrent que par leur nom et résident sur le même niveau d'abstraction, leur faire une exception, et de mettre les différents noms dans le message ou un seul champ de cette classe d'exception.

c) au moins en Java, il y a la discussion sur les exceptions vérifiées. J'enveloppe ceux qui sont directement dans un un sans contrôle, parce que je déteste le genre vérifié. Mais cela est plus une opinion alors des conseils.

Y at-il le cas où vous obtiendriez NoConnectionException qui n'est pas causée par un problème IO? A l'inverse, est de savoir si la cause est IO basée ou ne va pas aider le client à récupérer sensiblement?

  

Quand devez-vous jeter une exception personnalisée?

. Lorsque vous pouvez fournir des informations plus (diagnostic).

Remarque: ces informations supplémentaires peuvent ne pas être disponibles à l'endroit où l'exception d'origine (IOException) a été levée. couches d'abstractions progressives peuvent avoir plus d'informations à ajouter comme qu'est-ce que vous essayez de faire ce qui a conduit à cette exception?

II. Lorsque vous ne devez pas exposer les détails de mise en œuvre: à savoir que vous voulez que la (illusion?) Abstraction pour continuer.

Cela peut être important lorsque le mécanisme de mise en œuvre sous-jacente peut changer. Enroulant l'exception sous-jacente à une exception personnalisée est une bonne façon d'isoler vos clients à partir de détails de mise en œuvre (en soulevant le niveau d'abstraction)

III. Les deux I et II

NOTE: De plus vos clients devraient être en mesure de régler dans le niveau exact des informations qui les intéressent ou plutôt ils devraient pouvoir faire la sourde oreille tout ce qu'ils ne sont pas intéressés Il est donc une bonne idée de tirer vos exceptions personnalisées à partir. IOException.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top