pseudo-archive Java 
Réalisation

conception de classes et utilisation des exceptions
Bonjour à vous,

  Je me pose une petite question existancielle :o). Je suis en train de
  faire un package
et pour gérer les erreurs je me disais la chose suivante:
- pour les méthodes 'private' de ma classe qui sont appelées par des
fonctions internes à ma classe, je vais utiliser un code de retour qui
indique les erreurs qui ont pu survenir. J'utilise soit un booléen, soit
un entier. - pour les méthodes 'public' je n'utilise pas de valeur de
retour pour indiquer les erreurs, je vais utiliser des exceptions qui sont
en rapport avec ma classe.

Que pensez-vous de cette approche ? Est-elle 'logique' avec une conception
Java ? Me trompe-je ? :o)

Cordialement.
-- 
            .------------------------------------------------.
    .^.     | Didier Bretin, France | dbr@informactis.com    |
    /V\     |-----------------------| www.informactis.com    |
   // \\    |                       `------------------------|
  /(   )\   | Visit: http://www.vim.org/                     |
   ^^-^^    `------------------------------------------------'


> Bonjour à vous,
> 
>   Je me pose une petite question existancielle :o). Je suis en train de
>   faire un package
> et pour gérer les erreurs je me disais la chose suivante:
> - pour les méthodes 'private' de ma classe qui sont appelées par des
> fonctions internes à ma classe, je vais utiliser un code de retour qui
> indique les erreurs qui ont pu survenir. J'utilise soit un booléen, soit
> un entier. - pour les méthodes 'public' je n'utilise pas de valeur de
> retour pour indiquer les erreurs, je vais utiliser des exceptions qui
> sont en rapport avec ma classe.
> 
> Que pensez-vous de cette approche ? Est-elle 'logique' avec une
> conception Java ? Me trompe-je ? :o)

Selon moi oui car l'utilisation des exceptions a plusieurs avantages:
-séparation du code de gestion d'erreur du code applicatif 'normal'
-gestion fine des différents types d'erreur avec l'utilisation d'une
hiérarchie d'exception adéquate (on lance des exceptions de niveau le plus
fin possible mais on est libre de catcher au niveau qu'on veut)

Mais bon libre à toi de faire 'à la C' ou pire 'à la VB' avec des codes de
retour ;-)

Patrice

-- 


-- Use Opera, the most user-friendly browser on earth --
Powered by Outblaze



----- Original Message -----
From: "Didier Bretin" <dbr@informactis.com>
To: <java@u-strasbg.fr>
Sent: Friday, April 26, 2002 12:08 PM
Subject: conception de classes et utilisation des exceptions


> Bonjour à vous,
>
>   Je me pose une petite question existancielle :o). Je suis en train de
faire un package
> et pour gérer les erreurs je me disais la chose suivante:
> - pour les méthodes 'private' de ma classe qui sont appelées par des
fonctions internes à
> ma classe, je vais utiliser un code de retour qui indique les erreurs
> qui
ont pu survenir.
> J'utilise soit un booléen, soit un entier.
> - pour les méthodes 'public' je n'utilise pas de valeur de retour pour
indiquer
> les erreurs, je vais utiliser des exceptions qui sont en rapport avec ma
classe.
>
> Que pensez-vous de cette approche ? Est-elle 'logique' avec une
> conception
Java ?
> Me trompe-je ? :o)

Ben...heu...peut-être...
Les exceptions ne sont pas, selon moi, là pour renvoyer un résultat par
une voie spéciale (ce que semble suggérer cette distinction entre les
méthodes private et les autres). Pour moi, les exceptions sont plutôt là
pour signaler qu'un traitement a pris fin pour une raison inattendue. Et
cette fin inattendue peut avoir lieu aussi bien dans une méthode private
que dans une autre. Je m'explique : si dans une méthode private tu essayes
d'accéder à un fichier qui n'existe pas, tu recevras une
NoSuchFileException. Qu'en faire ? Selon ta logique, tu l'attrapes et tu
renvoies une valeur false, ce qui implique que tu as perdu de
l'information (le type d'exception qui est survenue notamment) alors que
si tu la propages, il arrivera probablement un moment où il sera
fonctionnellement normale de l'attraper (par exemple, dans une méthode
proche de l'IHM où tu signaleras que "le fichier n'existe pas"). En clair,
personnellement, je ne me soucie pas de savoir si il s'agit d'une méthode
private ou non pour renvoyer des exceptions. Je me pose cette unique
question :s 'agit-il d'un cas simple (où je peux dire que ça a marché oui
ou non) dans lequel je renverrai oui ou non, ou s'agit-il au contraire
d'un traitement plus complexe où l'appelant peut avoir besoin de savoir ce
qui s'est passé. Cette question suffit généralement à déterminer si on
renvoie un booléen d'état, un objet ou si on prévoit l'émission
d'exception. Il est à noter qu'on se palce dans un cas complexe dès que
quelqu'un dit "ce serait bien de savoir pourquoi ça n'a pas marché", ce
qui arrive tout de même très souvent. Pour moi, le résultat vrai/faux
n'est donc utilisable que pour une tâche totallement isolée, et surtout ne
peut exprimer qu'un résultat fonctionnel, et non un résultat organique.
Par exemple, si dans un client de mail j'ai une méthode hasNewMail, cette
méthode renverra true si du courrier est arrivé, false si aucun courrier
n'est arrivé, et une exception si on n'a pas pu se connecter au serveur. >
> Cordialement. > -- >            
.------------------------------------------------. >     .^.     | Didier
Bretin, France | dbr@informactis.com    | >     /V\    
|-----------------------| www.informactis.com    | >    // \\    |        
              `------------------------| >   /(   )\   | Visit:
http://www.vim.org/                     | >    ^^-^^   
`------------------------------------------------' > Nicolas Delsaux


Le 26 Apr 2002 Didier Bretin a écrit :

> 
> Que pensez-vous de cette approche ? Est-elle 'logique' avec une
> conception Java ? Me trompe-je ? :o)
> 

Moi je crois que tu devrais utiliser les exceptions partout, sauf cas très
particulier, mais je n'en ai pas d'exemple. Cela n'apporte pas grand chose
de renvoyer un booleen d'erreur à tester.

Voici comment je fais pour les exceptions.

Je renvoie par un throw, sans autre forme de procés, toutes les 
exceptions qui se produisent au sein des méthodes private et 
protected. Je considère qu'elles font des traitements internes pour 
d'autres traitements internes, et si quelque chose fontionne mal, ce n'est
pas à un niveau "interne interne" de s'en occuper. Il y a quelques
exceptions à ce principe, toutefois, mais c'est assez rare.

Le traitement réel des exceptions a lieu au niveau des méthodes 
publiques. En effet, à ce niveau, une entité extérieure attend un 
service. Si ce service n'a pu se dérouler correctement, le 
"prestataire" doit être en mesure d'expliquer pourquoi, et de se 
remettre dans un état correct.

Deux fonctions existent donc : expliquer, et se remettre dans un état
correct.

Pour la partie "expliquer", j'ai pour principe de toujours renvoyer 
une exception en rapport avec l'appel, plus formellement une 
exception d'un paquage identique aux composants de l'appel.

Par exemple si je prends la classe URL, la signature de l'un des 
constructeurs est :

public URL(String spec) throws MalformedURLException

Cette signature se comprend très bien : si "spec" est n'importe quoi, mon
URL sera mal formée, tout est clair. MalformedURLException fait partie du
paquage java.net, comme URL. Tout va bien.

Mais dans aue autre méthode de la classe URL, j'ai :

public URLConnection openConnection() throws IOException

D'où peut sortir cette IOException ??

Pour le comprendre, il faut savoir que URLConnection est une classe 
qui ressemble de loin à une entrée / sortie, bien que ce ne soit pas
immédiat, et que on peut imaginer que par une sorte de prémonition le
système renvoie une IOException... Ce n'est pas clair du tout, et je
trouve que Sun aurait dû renvoyer à cet endroit une ConnectException.

A+.

--
Sur le Web, tout de suite.
Herve AGNOUX - diaam informatique
http://www.diaam-informatique.com


At 14:50 2002-04-26 +0200, you wrote:
Le 26 Apr 2002 Didier Bretin a écrit :

> 
> Que pensez-vous de cette approche ? Est-elle 'logique' avec une
> conception Java ? Me trompe-je ? :o)
> 

Je renvoie par un throw, sans autre forme de procés, toutes les 
exceptions qui se produisent au sein des méthodes private et 
protected. Je considère qu'elles font des traitements internes pour 
d'autres traitements internes, et si quelque chose fontionne mal, ce 
n'est pas à un niveau "interne interne" de s'en occuper. Il y a 
quelques exceptions à ce principe, toutefois, mais c'est assez rare.
C'est l'approche que je préconise également. C'est aussi ce que suggère Bruce Eckel dans son livre "thinking in Java" au chapitre 9:

An exceptional condition is a problem that prevents the continuation of the method or scope that you’re in. It’s important to distinguish an exceptional condition from a normal problem, in which you have enough information in the current context to somehow cope with the difficulty. With an exceptional condition, you cannot continue processing because you don’t have the information necessary to deal with the problem in the current context. All you can do is jump out of the current context and relegate that problem to a higher context. This is what happens when you throw an exception.

Le traitement réel des exceptions a lieu au niveau des méthodes 
publiques. En effet, à ce niveau, une entité extérieure attend un 
service. Si ce service n'a pu se dérouler correctement, le 
"prestataire" doit être en mesure d'expliquer pourquoi, et de se 
remettre dans un état correct.

Deux fonctions existent donc : expliquer, et se remettre dans un état 
correct.
Je ne suis pas d'accord. Une exception indique une erreur grave qui implique un branchement vers d'autres instructions ou bien l'arrêt du logiciel afin d'informer l'utilisateur que l'opération a échoué. Tenter de corriger la provenance de l'exception (comme par exemple en incluant les "try/catch" dans un "while") s'avère difficile et peut aussi échouer. C'est en fait la problématique mieux connu sous le nom "termination vs resumption" et le choix fondamental que les concepteurs de Java ont fait est de supporter le premier. Voici d'ailleurs ce qu'a écrit Bruce Eckel à ce sujet:

Termination vs. resumption
There are two basic models in exception-handling theory. In termination (which is what Java and C++ support), you assume the error is so critical there's no way to get back to where the exception occurred. Whoever threw the exception decided that there was no way to salvage the situation, and they don't want to come back.

The alternative is called resumption. It means that the exception handler is expected to do something to rectify the situation, and then the faulting method is retried, presuming success the second time. If you want resumption, it means you still hope to continue execution after the exception is handled. In this case, your exception is more like a method call - which is how you should set up situations in Java in which you want resumption-like behavior. (That is, don't throw an exception; call a method that fixes the problem.) Alternatively, place your try block inside a while loop that keeps reentering the try block until the result is satisfactory.

Historically, programmers using operating systems that supported resumptive exception handling eventually ended up using termination-like code and skipping resumption. So although resumption sounds attractive at first, it seems it isn't quite so useful in practice. The dominant reason is probably the coupling that results: your handler must often be aware of where the exception is thrown from and contain non-generic code specific to the throwing location. This makes the code difficult to write and maintain, especially for large systems where the exception can be generated from many points.

Sylvain

Le 26 Apr 2002 scliche@matrox.com a écrit :

> C'est l'approche que je préconise également. C'est aussi ce que 
> suggère Bruce Eckel dans son livre "thinking in Java" au chapitre 9:
> 

Alors ça ! Je suis aussi génial que Bruce Eckel ! (et de toi, 
"scliche").


> [...]
>     Deux fonctions existent donc : expliquer, et se remettre dans un
>     état correct.
> Je ne suis pas d'accord. Une exception indique une erreur grave qui
> implique un branchement vers d'autres instructions ou bien l'arrêt du
> logiciel afin d'informer l'utilisateur que l'opération a échoué. Tenter
> de corriger la provenance de l'exception (comme par exemple en incluant
> les "try/catch" dans un "while") s'avère difficile et peut aussi
> échouer. C'est en fait la problématique mieux connu sous le nom

Je me suis mal exprimé : "se remettre dans un état correct", ce n'est pas
forcément tenter de corriger l'erreur. C'est se mettre dans un état tel
que l'on puisse répondre à la prochaine sollicitation, bien que l'on
vienne de subir une erreur.

Ce n'est pas dans le but de refaire le traitement, c'est dans le but de
pouvoir répondre correctement à une autre demande.


--
Sur le Web, tout de suite.
Herve AGNOUX - diaam informatique
http://www.diaam-informatique.com