2009-10-16 4 views
0

Lorsque je conçois une classe, j'ai souvent du mal à décider si je devrais lancer une exception ou si j'ai 2 func avec le 2ème renvoyant une valeur err. Dans le cas de 2 fonctions, comment nommer la méthode d'exception et de non-exception? Par exemple, si j'écris une classe qui décompresse un flux et que le flux contient des erreurs ou incomplètes, je lance une exception. Cependant, que se passe-t-il si l'application tente de récupérer des données du flux et exclut une erreur? Il voudrait une valeur de retour à la place? Alors, comment dois-je nommer la 2ème fonction?Conception d'une classe avec ** Exceptions **

Ou ne devrais-je pas avoir à la fois une méthode d'exception et une méthode de non-perception?

+0

Cela ne me semble pas être particulièrement agnostique. Dans le cas extrême, si vous utilisez C, vous ne lancez pas d'exceptions. En C++, vous devez quand même concevoir pour la sécurité des exceptions. Dans d'autres langues, des exceptions peuvent être disponibles mais pas obligatoires. –

Répondre

2

Ou ne devrais-je pas avoir à la fois une méthode d'exception et une méthode de non-perception?

Cela. Sauf si vous avez vraiment temps de graver en conservant deux méthodes distinctes mais la plupart du temps identiques.

Si vous avez vraiment besoin d'autoriser des clients qui ne considéreront pas les erreurs comme exceptionnelles, indiquez-les simplement avec une valeur de retour et faites-en la fin ... Sinon, écrivez simplement la version d'exception et laissez l'erreur Le client gérant l'exception.

+0

Je voudrais avoir l'exception jeter appelez la méthode return val et PAS avoir le code de répétition. Mais je suis d'accord avec toi. Je vais l'écrire pour lancer une exception, puis la changer pour retourner la valeur si j'en ai besoin. –

1

Je crois que vous devriez essayer d'utiliser des exceptions même si vous n'allez pas quitter le programme dans certains cas. Vous avez juste besoin de créer un type d'exception spécifique pour vos erreurs. Et attrapez-les seulement quand vous avez besoin de faire une certaine logique spefic. Toutes les autres exceptions iront au niveau supérieur de votre code. Par exemple, vous avez créé une fonction qui déclenche une exception lors d'une erreur. Et vous ne voulez pas quitter le programme si l'utilisateur a spécifié un nom de fichier incorrect. Voici comment il peut regarder:

## this is top level try/catch block 
try { 
    ## your main code is here 
    ... 
    ## somewhere deep in your code 
    try { 
     ## we trying to open file specified by user 
    } 
    catch (FileNotFoundException) { 
     ## we are not going to exit on this error 
     ## let's just show a user an error message 
     ## and try to ask different file to open 
    } 

} catch (Exception) { 
    ## catch all exceptions here 
    ## the best thing we can do here is save exception to log and quit } 
} 

Nous avons juste besoin de créer hiérarchie des exceptions (si votre langue permet):

Exception <-- MoreSpecificException 

Cette approche est utilisée en Java

+1

OTOH, si le code appelant ces routines attrape immédiatement ces exceptions * la plupart du temps *, alors il est un peu plus verbeux que le code de valeur de retour équivalent. Et ... pas vraiment exceptionnel! – Shog9

+0

Vous pouvez toujours créer une autre fonction qui convertira simplement l'exception en code de retour. Mais il faut faire attention. Le plus gros problème avec les codes d'erreur est que personne ne les vérifie, et s'ils sont cochés, le code peut devenir très compliqué. –

+1

La question d'origine n'est liée à aucune langue spécifique. Le conseil de "vous devriez essayer d'utiliser des exceptions même si vous n'allez pas sortir du programme dans certains cas" est certainement vrai et approprié dans certaines langues (Java, C#), mais est certainement faux dans d'autres (par exemple Objective-C) . – harms

2

Il dépend À mon avis, deux versions de chaque méthode potentiellement défaillante imposent un fardeau cognitif trop lourd à l'utilisateur de l'API, et un fardeau trop lourd pour le responsable de l'API. Ma préférence personnelle est pour les exceptions, puisque c'est moins de paramètres pour se souvenir de l'ordre de.

0

Je ne lancerais une exception sur la fonction de décompression que si les résultats n'étaient pas utilisables. Si elles étaient utilisables, renvoyez les résultats, puis la fonction qui lit ces résultats peut lancer une exception à la place. IE

try 
{ 
    results = decompress(file); // only throws exceptions on non-usable files 
} catch (FileNotFoundException) { 
    // file was not usable, can't recover anything, insert nuclear error handling here 
} 
try 
{ 
    read(results); 
} catch (ErrorThatIsRecoverableException) { 
    partialRead(results); 
} 

afin de lire() est la fonction que vous faites appel à des données normales, partialRead est la fonction qui gère en essayant de récupérer vissé-up mais-encore utilisables données. Et bien sûr, vous n'avez pas forcément besoin d'exceptions ou de fonctions séparées - vous pourriez faire l'erreur de gérer tout dans la fonction read().

1

Des exceptions devraient normalement être utilisées pour des conditions exceptionnelles, quelles qu'elles soient. Etre incapable de décompresser un fichier est probablement une condition exceptionnelle (à moins, par exemple, que vous écriviez un programme pour analyser des fichiers mal compressés). Les mauvaises données peuvent être ou ne pas être exceptionnelles.

Si vous avez une classe décompressant un flux, alors ce qu'il doit faire est décompresser le flux, et ne pas essayer d'interpréter son contenu. Une autre classe devrait utiliser la première classe pour obtenir une entrée décompressée, et faire l'interprétation. Cela vous donne la séparation des fonctionnalités et une bonne cohésion. Évitez les classes où vous êtes tenté de mettre un "Et" dans leur nom: "DecompressAndParseInput" est un mauvais nom de classe.

Étant donné deux classes, il n'y a pas de raison particulière pour laquelle vous devez utiliser la même méthode de génération d'erreur pour les deux. Le décompresseur peut lancer et l'analyseur peut renvoyer un code d'erreur.

Questions connexes