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

  1. #21
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    hibour: j'ai dit le plus rapide dans le sens "le plus rapide à coder" pas le plus performant à l'exécution Quand aux ^$ c'est une habitude

  2. #22
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Les chiffres arabes sont ceux qu'on écrit tous

  3. #23
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 704
    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 704
    Par défaut
    D'ailleurs les chiffres arabes ont été inventés en inde

  4. #24
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par hibour Voir le message
    Les chiffres arabes sont ceux qu'on écrit tous
    faut réviser tes langues, je parle bien des chiffres arabes
    http://fr.wikipedia.org/wiki/Num%C3%A9ration_arabe

    ٠ ١ ٢ ٣ ۴ ۵ ۶ ٧ ٨ ٩

    et toc

  5. #25
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Ces chiffres arabes (à priori arabo-indiens) sont utilisés surtout dans les pays arabe de moyen orient (arabie saoudite, emirat arabe, liban..) et pas en maghreb qui lui utilise les nombre arabes proprement dit (0, 1, 2 ..)

  6. #26
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par hibour Voir le message
    Pill_S: Effectivement ton code est un peu plus performant dans le cas où la taille du tableau est très grande (> 100.000 éléments)
    C'est peut-être un peu plus performant sur de très grand tableau, mais sur des tableaux plus raisonnable cela s'avère nettement moins performant !

    Mais surtout ceci donne un code relativement affreux...


    Citation Envoyé par tchize_ Voir le message
    et qui, notez le bien, fait 3 lignes de moins Je crois que cet exemple est très bon car utilisé par beaucoup, dans une méthode potentiellement fortement utilisée (on pourrait imaginer qu'une boucle de traitement sur un document texte l'utilise pour savoir si oui ou non on est face à un nombre afin de décider d'un traitement) et ou donc l'utilisation d'exceptions est préjudiciables.
    +1
    C'est vrai qu'il y a le problème du parse() qui ne traite pas forcément toute la chaine...


    Mais je voulais surtout souligné que le problème venait du fait que l'exception était ici utilisé dans un cas de terminaison normale. En effet dans ce cas précis il est tout à fait normal de passer à la méthode une chaine qui ne soit pas un nombre. Et dans ce cas on génère une exception dans un cas normal d'utilisation.

    Ce n'est pas bien méchant la plupart du temps, mais en cas d'appel intensif les multiples créations d'exception peuvent s'avérer très couteuse à cause de la génération du stacktrace.




    A noter tout de même que depuis Java 6 le coût de la génération du stacktrace s'est grandement réduit, et que l'impact est donc bien moins important...

    a++

  7. #27
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    essaie pas de te sauver, les nombres 0 1 2 3 4 5 6 7 8 9 , appelé "nombres arabes" ne s'écrivaient pas de la même manière en arabe dès l'orginie, c'est jsute le concept et vaguement la notation qui a été piquée à l'époque, le terme correct devraient d'ailleurs etre "nombres européens" :p

    Je parlais bien de la langue arabe, qui possède son propre range de caractères unicode pour les chiffres. D'facon mon collègue confirme: pour une partie des pays d'afrique du nord, c'est chiffres européens, pour une autres (tunisie, Egypte) c'est les "vrais" chiffres arabes.

    Puis j'ai raison et t'as tord

  8. #28
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Je suis maghrébin c'est pour ça j'ai insisté sur ces chiffres
    Il y a un cas où on peut avoir besoin de lancer une fausse exception juste pour logger le nom de la méthode où on est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try {
        throw new Throwable();
    } catch(Throwable t) {
      System.out.println("On est dans la méhode " + t.getStackTrace()[0].getMethodName());
    }

  9. #29
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par hibour Voir le message
    Il y a un cas où on peut avoir besoin de lancer une fausse exception juste pour logger le nom de la méthode où on est
    Oui mais c'est autre chose encore puisqu'ici on a besoin des infos du stacktrace. Par contre il faut éviter de généraliser cela car cela pourrait s'avérer très couteux en fin de compte...


    Au passage il n'y a pas besoin de remonter l'exception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    StackTraceElement[] stack = new Throwable().getStackTrace();
    // ou encore (équivalent pour le thread courant) :
    StackTraceElement[] stack = Thread.currentThread().getStackTrace();
    Mais bon cela ne change pas grand chose car tout le coût de l'opération survient lors de la création du stacktrace...


    a++

  10. #30
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    On ne peut pas gagner à tout les coup.. Cela m'interpelle une autre discussion où j'ai dit Généralisation VS Optimisation, Il faut trouver le bon compromis

  11. #31
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Oui en effet.

    Pour en revenir au sujet initial, une exception doit être fait pour remonter une erreur et non pas pour traiter un cas particulier.

    Si ce n'est pas le cas il faut se poser des questions pour être sûr de ce que l'on fait.

    a++

  12. #32
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Je suis tout à fait d'accord, les exceptions sont là pour traiter des cas incohérents (business, fonctionnel).
    Ne pas s'amuser à créer des millions de type d'exceptions si un type existant peut faire l'affaire.
    Ne pas wrapper les exception aveuglément dans d'autres types car c'est plus difficile de retrouver ensuite la vraie raison de l'exception.
    Perso je préfère wrapper une checked Exception dans un RuntimeException dans la mesure du possible (méthodes interne) pour ne pas être obligé de faire des try-catch partout
    Voilà mon point de vue

  13. #33
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par hibour Voir le message
    Pill_S: Effectivement ton code est un peu plus performant dans le cas où la taille du tableau est très grande (> 100.000 éléments) car en interne la JVM vérifie l'index d'un tableau, donc avec une boucle normal on fait une double vérification de l'index.
    ca s'appelle de l'optimisation hâtive (un autre anti pattern tiens). On optimise avant de savoir où il faut optimiser. Même si ce code est un peu plus rapide que de faire un check dans le for(), il faut être réaliste. Le test sur la taille du tableau occupe une instruction CPU, alors que, rappelons le, nous avons un code dans la boucle qui appelle deux méthodes au contenu inconnu. De deux choses l'une. Soit le contenu de la boucle met du temps à s'exécuter -> alors c'est pas une lecture de propriété qui changera quoi que ce soit.
    Soit le contenu de la boucle est rapide -> alors on s'en tappe, c'est pas un point chaud du code.

    Pour référence, j'ai fait un code qui, 5.000.000 fois, fait le XOR de tout un tableau de 500.000.000 (500 millions d'entrées, oui) de int. Avec un boucle "classique" on se stabilise à 428ms au total, avec un boucle "exception" on se stabilise à 1776ms. Donc sur ma machine, exceptions, ca veut dire 4* plus de temps sur un boucle rapide. Si la boucle avait été lente, la différence ne se serait pas faite sentir. conclusion, on ne gagne rien avec l'exception, mais on risque de perdre.

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    public class TestSpeed {
    	private static final int ARR_SIZE = 500000000;
    	static int TEST = 123456;
    	private static void maMethode(int i){
    		TEST=TEST^i;
    	}
    	public static void main(String[] argv) {
    		System.out.println("allocating");
    		int[] arr = new int[ARR_SIZE];
     
    		for (int i= 0; i< ARR_SIZE; i++){
    			arr[i]=i;
    		}
    		System.out.println("done");
    		for (int i=0; i< 10; i++){
    			long init = System.currentTimeMillis();
    			testSpeed(arr);
    			long end = System.currentTimeMillis();
    			System.out.printf("Temps moyen pour méthode classique: %d ms\n",end-init);
    			init = System.currentTimeMillis();
    			testSpeed2(arr);
    			end = System.currentTimeMillis();
    			System.out.printf("Temps moyen pour méthode Exception: %d ms\n",end-init);
    		}
    	}
    	private static void testSpeed2(int[] arr) {
    		for (int i = 0; i < 5000000; i++);
    		{
    			int j = 0;
    			try{
    				while(true){
    					maMethode(arr[j++]);
    				}
    			} catch (ArrayIndexOutOfBoundsException e){}
    		}
     
    	}
    	private static void testSpeed(int[] arr){
    	for (int i = 0; i < 5000000; i++);
    	{
    			for (int j=0; j<arr.length;j++){
    				maMethode(arr[j]);
    			}
    	}
     
    }
     
    }
    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
    Temps moyen pour méthode classique: 488 ms
    Temps moyen pour méthode Exception: 2061 ms
    Temps moyen pour méthode classique: 463 ms
    Temps moyen pour méthode Exception: 1816 ms
    Temps moyen pour méthode classique: 427 ms
    Temps moyen pour méthode Exception: 1775 ms
    Temps moyen pour méthode classique: 427 ms
    Temps moyen pour méthode Exception: 1778 ms
    Temps moyen pour méthode classique: 427 ms
    Temps moyen pour méthode Exception: 1776 ms
    Temps moyen pour méthode classique: 424 ms
    Temps moyen pour méthode Exception: 1776 ms
    Temps moyen pour méthode classique: 426 ms
    Temps moyen pour méthode Exception: 1776 ms
    Temps moyen pour méthode classique: 425 ms
    Temps moyen pour méthode Exception: 1776 ms
    Temps moyen pour méthode classique: 426 ms
    Temps moyen pour méthode Exception: 1775 ms
    Temps moyen pour méthode classique: 423 ms
    Temps moyen pour méthode Exception: 1776 ms
    PS: on vois bien sur les premier run que le JIT essaie d'améliorer els perfs au fur et à mesure :p

  14. #34
    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 : 77
    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 hibour Voir le message
    Perso je préfère wrapper une checked Exception dans un RuntimeException dans la mesure du possible (méthodes interne) pour ne pas être obligé de faire des try-catch partout
    je ne voudrais pas relancer une nouvelle polémique sur ce sujet (sur lequel tout le monde s'étripe) mais là je désapprouve fortement.
    mais ceci, comme dit le conteur, est une autre histoire ....

  15. #35
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    je ne voudrais pas relancer une nouvelle polémique sur ce sujet (sur lequel tout le monde s'étripe) mais là je désapprouve fortement.
    Oui une nouvelle polémique


    Encore une fois cela dépend beaucoup du contexte, mais perso j'utilise beaucoup cela pour les exceptions qui ne doivent pas arriver dans une utilisation normale de l'application.

    Cela permet d'avoir un code "fail-fast"

    a++

  16. #36
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 704
    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 704
    Par défaut
    Pour relancer le débat j'ai eu une idée pour les exception plus rapide si on se moque du stacktrace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class UntracedException extends Exception {
        public synchronized Throwable fillInStackTrace() { return this; }
    }
    avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for (long i = 0; i < 1000000L; i++) {
      try {
        throw new /*Untraced*/Exception();
      } 
      catch (Exception e) {}
    }
    Je passe de environ 1300 ms à environ 300 ms, ceci dit je suppose qu'avec une trace plus compliquée à générer on doit gagner plus

  17. #37
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Uther Voir le message
    Pour relancer le débat j'ai eu une idée pour les exception dont quand on se moque du stacktrace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class UntracedException extends Exception {
        public synchronized Throwable fillInStackTrace() { return this; }
    }
    Oui mais là on est en plein dans l'anti-pattern : à quoi peut bien servir une exception qui ne contiendrait aucune info sur l'erreur !?

    a++

  18. #38
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 704
    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 704
    Par défaut
    C'est vrai que j'ai un peu trop simplifié mon exemple, mais on pourrait garder toutes les infos (sauf la stacktrace).

  19. #39
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Si tu n'as pas besoin de la stacktrace, il y a de forte chance que les exceptions ne soient pas la solution au problème

    Dans un cas d'erreur le coût de génération de la stacktrace est minime par rapport à son utilité.

    a++

  20. #40
    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
    Bon au vu du nombre de réponses je me dis que c'était pas aussi évident que ça ....

    Si on reprend l'exemple de professeur shadoko il y a en gros 2 implémentations possible que je vois :
    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
    24
    25
    26
    27
    28
    29
    30
     
     
    	private void solution1() {
    		// TODO Auto-generated method stub
     
    	double demandeRetrait = 15;
     
    	CompteEnBanque compteEnBanque = new CompteEnBanque();
     
    	try {
    		compteEnBanque.retrait(demandeRetrait);
    	} catch (ExceptionDepassementDecouvert e) {
    		// TODO Auto-generated catch block
    		log.info("Vous avez dépassé le montant du compte");
    	}
     
    	}
     
    	private void solution2() throws ExceptionDepassementDecouvert {
    		// TODO Auto-generated method stub
    		double demandeRetrait = 15;
     
    		CompteEnBanque compteEnBanque = new CompteEnBanque();
    		if (compteEnBanque.getSolde() > demandeRetrait){
    				compteEnBanque.retrait(demandeRetrait);
    		}else{
    			log.info("Vous avez dépassé le montant du compte");	
    		}
     
    	}
    D'après ce qui ressort de la discussion la bonne solution est la solution 2 (malgré le fait qu'il y ai redondance du test compteEnBanque.getSolde() > demandeRetrait)

    Vous confirmez ?

Discussions similaires

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

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