IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Anti-pattern : exception métier


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    333
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 333
    Par défaut Anti-pattern : exception métier
    Bonsoir,

    Suite à une discussion avec un collègue, celui-ci m'a indiqué qu'utiliser le système d'exception de java pour traiter des cas métier (faire ses propres exceptions )dans une application était un anti-pattern classique.

    Son argument principal était les performances, les stacktraces consomment beaucoup....

    Je n'ai personnellement jamais utilisé d'exceptions personnalisées pour traiter des cas métier dans le cadre d'une grosse application, donc j'ai du mal à me faire une opinion.

    Une petite recherche google ne m'a vraiment convaincu de l'existence de cet anti-pattern ! Qu'en pensez vous ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Citation Envoyé par LittleBean Voir le message
    Suite à une discussion avec un collègue, celui-ci m'a indiqué qu'utiliser le système d'exception de java pour traiter des cas métier (faire ses propres exceptions )dans une application était un anti-pattern classique.
    Attention, "faire ses propres exceptions" ne veut pas dire "utiliser le système d'exception de java pour traiter des cas métier".

    La création d'une exception est en effet assez lourde, c'est pourquoi il faut réserver les levées d'exceptions aux réels cas d'erreur, peu fréquents.
    Ce qu'il ne faut pas faire, c'est utiliser les exceptions pour gérer les cas métiers, c'est-à-dire les différents cas prévisibles sur lesquels on s'attend à tomber dans le cadre d'une utilisation normale de l'application.

    L'utilisation d'exceptions "personnalisées" est en revanche tout à fait normale, dans le cadre de la gestion d'erreurs.

  3. #3
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    je suis un peu surpris là .... on pourrait avoir un exemple pour comprendre?

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Un exemple à la con :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public static void traitement(String arg)
    throws BonjourException, AuRevoirException, UnexpectedArgException
    {
       if (arg.equals("bonjour")) throw new BonjourException();
       else if (arg.equals("aurevoir")) throw new AuRevoirException();
       else throw new UnexpectedArgException("Cet argument n'est pas valide. Arguments acceptés : 'bonjour' et 'aurevoir'.");
    }
     
    public static void main(String[] args)
    {
       try {
          traitement(args[0]);
       }
       catch (BonjourException e) {
          System.out.println("Bonjour !");
       }
       catch (AuRevoirException e) {
          System.out.println("Au revoir !");
       }
       catch (UnexpectedArgException e) {
          System.out.println(e.getMessage());
       }
    }
    Dans cet exemple la méthode traitement a trois points de sortie : deux points de sortie "normaux" (l'argument vaut 'bonjour' ou 'aurevoir') et un point de sortie d'erreur (l'argument ne fait pas partie de la liste des arguments acceptés).
    L'utilisation d'une exception pour l'erreur d'argument ne pose pas de problème: l'utilisateur est censé avoir lu la doc et lancer l'application avec le bon argument, il s'agit donc d'un cas d'erreur "exceptionnel"...
    Par contre, s'amuser à lancer des exceptions pour différencier les cas d'utilisation "normaux", c'est une utilisation abusive du système des exception.

    Bon, ici, mon exemple est très artificiel, il doit y avoir des cas où l'utilisation d'une exception en tant que point de sortie "normal" d'une méthode doit paraître moins absurde
    Mais en gros le problème c'est quand on commence à utiliser les exceptions pour transporter des informations sur un traitement "normal" au lieu d'utiliser par exemple des valeurs de retour et de réserver les exceptions aux cas d'erreur.

  5. #5
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Je confirme ce que dit Astaree, les exceptions comme leur nom l'indique sont prévues pour gérer les situations exceptionelles qui sortent du fonctionnement de base, typiquement des paramètres invalides, des ressources inaccessibles, ...
    Il est tout a fait valable d'en définir de nouvelles, mais elle ne devraient pas être utilisées pour un fonctionnement normal.

    Cependant, comme le dit LittleBean, la génération du stacktrace est couteuse.
    Si dans un programme critique au niveau performance, on se trouve dans la situation rare où l'on devra lever énormément d'exceptions qui correspondent pourtant bien à un comportement exceptionnel, cela peut être préjudiciable pour les performances pure.
    Dans ce cas là, une solution possible serait de faire une méthode de vérification séparée qui retournera un booléen et non une exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // objet.addParam retourne une ParamException si le paramètre est invalide
    if (objet.isParamValid(param)){
      objet.addParam(param);
    }

  6. #6
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par Uther Voir le message
    Je confirme ce que dit Astaree, les exceptions comme leur nom l'indique sont prévues pour gérer les situations exceptionelles qui sortent du fonctionnement de base, typiquement des paramètres invalides, des ressources inaccessibles, ...
    Il est tout a fait valable d'en définir de nouvelles, mais elle ne devraient pas être utilisées pour un fonctionnement normal.
    je dois être bouché mais j'ai vraiment besoin d'un exemple qui veuille dire quelque chose!
    Si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class CompteEnBanque {
           private double solde ; // je mets double pour simplifier
           private  double découvertAutorisé ; // idem
           /// codes
           public void retrait(double montant) throws 
                                     ExceptionDepassementDecouvert {
                   // code métier qui déclenche l'exception
          }
    }
    je ne vois pas en quoi ceci serait un anti-pattern.
    On a un "code appelant" qui demande un service et qui n'a pas de moyen de connaitre les conditions de l'echec de sa demande...
    Il est normal donc d'avoir une exception controlée pour signifier l'echec de la demande de service.
    Le contraire serait un drôle de détournement des principes de Java: avoir une méthode "à la fonction C" qui rendrait ....? quoi au fait?
    adopter une stratégie "à la C" aurait pour conséquence:
    - de laisser le code appelant écrire un code qui n'est pas forcé de prendre en compte l'échec du service.
    - de spécifier dans bien des cas un résultat de retour assez tordu
    (quid si la méthode doit déjà rendre un résultat "normal", quid si l'échec de service concerne un constructeur).
    Donc pour revenir à ma question initiale: un exemple pertinent svp. merci

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    333
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 333
    Par défaut
    Attention, "faire ses propres exceptions" ne veut pas dire "utiliser le système d'exception de java pour traiter des cas métier".
    Tout à fait d'accord c'est pour ça que j'ai rajouté une précision en parenthèse

    La création d'une exception est en effet assez lourde, c'est pourquoi il faut réserver les levées d'exceptions aux réels cas d'erreur, peu fréquents.
    Ce qu'il ne faut pas faire, c'est utiliser les exceptions pour gérer les cas métiers, c'est-à-dire les différents cas prévisibles sur lesquels on s'attend à tomber dans le cadre d'une utilisation normale de l'application.

    L'utilisation d'exceptions "personnalisées" est en revanche tout à fait normale, dans le cadre de la gestion d'erreurs.

    Est ce que tu pourrais détailler un peu plus ? Par exemple dans le cas où tu ne trouve pas un utilisateur en base ?

    Le seul argument contre cette pratique est les perf ?

    Edit : arg pas vu les 2 dernières réponses trop lent à poster :p
    => pour les exemples ok mais pour les contre argument je ne vois que les perf

  8. #8
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Par exemple pour reprendre l'exemple d'Astaree, La version propre serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static void traitement(String arg)
    throws BonjourException, AuRevoirException, UnexpectedArgException
    {
       if (arg.equals("bonjour")) System.out.println("Bonjour !");
       else if (arg.equals("aurevoir")) System.out.println("Au revoir !");
       else throw new UnexpectedArgException("Cet argument n'est pas valide. Arguments acceptés : 'bonjour' et 'aurevoir'.");
    }
     
    public static void main(String[] args)
    {
       try {
          traitement(args[0]);
       }
       catch (UnexpectedArgException e) {
          System.out.println(e.getMessage());
       }
    }
    On vois bien que le code de traitement exceptionnel est séparé du code de traitement normal ce qui est clairement plus propre. C'est le but des exceptions.

Discussions similaires

  1. Réponses: 10
    Dernier message: 06/10/2010, 17h06
  2. Les exceptions métiers
    Par zoaax dans le forum Général Dotnet
    Réponses: 12
    Dernier message: 15/04/2010, 14h31
  3. singleton == anti pattern?
    Par yan dans le forum C++
    Réponses: 5
    Dernier message: 17/04/2008, 14h17
  4. Réponses: 11
    Dernier message: 26/09/2007, 11h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo