2008-09-26 2 views
2

J'ai une classe qui encapsule les communications de socket tcp avec un serveur. Pour chaque message de commande envoyé au serveur, le serveur renvoie un message de réponse qui contient invariablement un code de réponse (OK, Fail). En utilisant ma classe, chaque commande peut être exécutée soit en synchronisation soit en asynchrone.Exceptions vs codes de résultat pour une classe de client de socket

Il existe essentiellement deux types d'exceptions: Un "défaut" provoqué par une déconnexion ou une autre erreur irrécupérable et une exception inattendue comme "envoyer le tampon est plein". En cas de panne, aucune commande ne peut continuer ou réessayer ou quoi que ce soit jusqu'à ce que la connexion soit rétablie. En cas de réponse d'échec ou même d'exception, la commande peut être réessayée ...

Ainsi, mes méthodes de commande de synchronisation retournent maintenant une énumération qui peut avoir les valeurs suivantes: OK, Fail, Fault. Si une exception se produit, elle est simplement portée au thread appelant (dans une commande de synchronisation). Pour les commandes async, la valeur enum de la propriété Result peut contenir une valeur supplémentaire: OK, Fail, Fault ou Exception et le rappel peut accéder à l'objet exception réel via la propriété Exception de l'objet de commande.

Que pensez-vous de cette stratégie? Je suis tenté de ne pas lever d'exception pour les commandes de synchronisation et de simplement consigner l'exception en interne et retourner la 4ème valeur enum parce que c'est tout ce que je ferai vraiment avec des exceptions dans tous les cas ... Ou, devrais-je codes de résultat du tout et juste soulever des exceptions dans tous les cas, même des fautes?

Merci.

+0

Merci pour toutes vos réponses. La valeur que j'ai obtenue de ce fil était essentiellement un rappel pour "utiliser des exceptions pour des conditions exceptionnelles". Donc, je donne la réponse à la première personne qui a dit cela. Si je pouvais donner plusieurs réponses, je le ferais! –

Répondre

1

Je pense que votre stratégie est fondamentalement saine. Gardez à l'esprit que le but des exceptions est de faire face à des conditions exceptionnelles. Le plus proche de la source du problème, mieux c'est.

Dans votre cas, il semble que votre stratégie ressemble à quelque chose comme: "Cela n'a pas fonctionné pour le moment, réessayons". Je ne vois pas de raison de vraiment soulever des exceptions.

Si la gestion d'une socket fermée nécessitait un flux totalement différent dans votre code, des exceptions auraient peut-être un sens. D'après votre description, ce n'est pas vraiment le cas. Ma philosophie sur les exceptions est qu'elles devraient être pour des conditions exceptionnelles que vous ne pouvez pas vraiment traiter avec. Une prise fermée? Hmm ... combien de fois l'internet descend-il chez moi ...

0

Les codes de résultat et les exceptions peuvent fonctionner correctement. C'est une question de goût personnel (et du goût des autres membres de votre équipe). Les exceptions présentent certains avantages, en particulier dans les configurations plus complexes, mais dans votre configuration, cela semble assez simple pour que les codes de retour fonctionnent correctement. Certaines personnes vont mousser à la bouche et insister sur des exceptions, mais sur mon projet, les gens aiment la simplicité des codes de retour, ce qui en fait le meilleur choix global.

0

Ceci est une question plutôt intéressante. En tant que tel, il n'y a probablement pas de réponse "100% correcte", et cela dépend surtout de la façon dont vous pensez que le code utilisant votre fonction devrait être structuré. Comme je le vois, vous n'utilisez des exceptions que lorsque vous voulez fournir le code appelant votre fonction avec un moyen d'échapper gracieusement à une situation «désastreuse». Donc, dans mon code, je lance normalement une exception quand quelque chose vraiment, vraiment arrive horrible, et l'appelant a besoin de savoir.Maintenant, si ce que vous avez est une situation normale, et attendue, vous devriez probablement retourner une valeur d'erreur. De cette façon, le code sait qu'il doit «essayer plus fort», mais il ne sera pas compromis par ce qui s'est passé. Dans votre cas, par exemple, vous pouvez traiter les délais d'attente comme prévus, et renvoyer ainsi un code d'erreur, ainsi que des problèmes plus graves (comme un tampon d'envoi complet) où le code appelant doit effectuer des actions supplémentaires. retour à 'normal' comme une exception. Mais alors, la beauté est dans l'oeil du spectateur, et certaines personnes vous diront de n'utiliser que des exceptions, d'autres (principalement des programmeurs C) pour utiliser uniquement des codes de retour. Rappelez-vous juste, les exceptions toujours être exceptionnelles. :)

1

Je préfère que vous lanciez une exception chaque fois que votre méthode ne termine pas sa mission avec succès. Donc, si je, l'appelant, appelez votreObjet.UploadFile(), je suppose que le fichier a été téléchargé avec succès lorsque l'appel revient. S'il échoue pour une raison quelconque, je m'attends à ce que votre objet lève une exception. Si vous voulez faire la distinction entre les commandes que je peux réessayer et les commandes que je ne devrais pas réessayer, mettez cette information dans l'exception et je peux décider comment réagir en conséquence. Lorsque j'appelle yourObject.BeginAsyncUploadFile(), je m'attendrais au même comportement sauf que j'aurais besoin d'attendre sur l'objet IAsyncResult ou équivalent pour savoir si le chargement du fichier a réussi ou non et ensuite vérifier une exception/Propriété d'erreur si ce n'est pas le cas.

Questions connexes