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

Langages de programmation Discussion :

Bonne pratique pour "if" ?


Sujet :

Langages de programmation

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    785
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 785
    Par défaut Bonne pratique pour "if" ?
    Bonjour,
    J'aurais voulue vous demander des conseils sur quelque chose qui m'arrive assez souvent. J'ai pas mal de "if" qui possède beaucoup de conditions dans le code (il m'arrive d'en avoir 5 ou 6 parfois) :
    Un peux comme l'exemple ci-dessous
    if(cube != null && cube.x>0 && cube.y>0 && !istrue &&... &&... &&... )
    {
    //code...
    }
    Est ce que c'est assez répandue, ou est ce que c'est plutôt signe que j'ai donné a une méthode trop de chose a faire et que je dois charger une autre méthode d'une partie du travail?

    Bonne journée,

  2. #2
    Membre Expert
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Billets dans le blog
    1
    Par défaut
    Personnellement, je dirais qu'il faut distinguer deux type de condition:
    1) Celle qui vérifie l'intégrité des données (comme le != null, != 0, IsNotEmpty ....)
    2) Celle qui vérifie les condition d'éxécution (isANumber, isInSquare, x < y ....)

    J'appelle condition d'éxécution, les conditions qui donnent un sens "fonctionnel" à une fonction, à un test etc ...

    Pour moi il faut impérativement faire les deux dans des if séparé afin d'avoir un traitement différent lorsque l'intégrité des données n'est pas vérifié.
    On pourrait imaginé ça:

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool IsAnimal(Entity* entity)
    {
      if (nullptr == entity) // Condition d'intégrité
        return (false);
      if (entity.IsACat() || entity.IsADog()) // Condition d'éxécution
        return (true);
      return (false);
    }

    plutot que:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool IsAnimal(Entity* entity)
    {
      if (nullptr != entity && (entity.IsACat() || entity.IsADog()))
        return (true);
      return (false);
    }

    Et ensuite ne pas tester des choses différente dans le même if, par exemple:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (entity.isACat() && entity.isGray())
      //traitement des chats gris
      if (entity.isACat() && entity.isYellow())
     // traitement des chats jaune

    mais plutot:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (entity.isACat())
    {
      if (entity.isGray())
        // traitement des chats gris
      else if (entity.isYellow())
        // Traitement des chats jaune
    }

    Ensuite je sais pas si il existe des standards là dessus .

  3. #3
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Ce n'est pas tant le nombre de conditions qui importe.

    L'ensemble est-il immédiatement compréhensible ? Si tu testes une non-nullité suivi de trois coordonnées x, y et z, il y a de bonnes chances que le lecteur comprenne de suite ce dont il s'agit. Si en revanche ta condition, même unique et simple, n'est pas évidente, il faut expliciter. Dans ce cas tu peux utiliser un commentaire (bof), ou bien créer une fonction intermédiaire (ça se défend), ou enfin ajouter une ligne pour préalablement stocker le résultat dans une variable au nom explicite, puis simplement tester la variable (souvent préférable).

    L'autre question est celle du niveau de détail et d'encapsulation. Le lecteur de la fonction doit-il percevoir les détails de cette condition ou simplement son but ? Les détails peuvent-ils être amenés à changer alors que le but sera toujours le même ? Si oui une fonction distincte est le bon choix.

    Le reste n'est qu'une question d'aération et d'organisation du code, avec une bonne part de subjectivité. En général on préfère les méthodes courtes pour la lisibilité de la fonction, mais de trop nombreuses méthodes nuisent à la lisibilité du type, et à la navigation dans le fichier. Pour ce genre de questions la référence contemporaine est "Clean Code", de Robert Martin.


    @skeud
    Je m'oppose à ta dichotomie entre conditions d'intégrité et d'exécution. Soit "null" signifie quelque chose de précis et est une valeur attendue, et alors c'est une condition comme une autre, soit "null" ne devrait pas se produire et dans ce cas tu ne devrais pas la gérer et laisser les appelants définir la façon de rétablir le bon fonctionnement du programme. Les erreurs inattendues doivent en effet être traitées au plus haut niveau possible, si besoin est en amputant une fonctionnalité ou en plantant le programme, plutôt que de tenter de les glisser sous le tapis en espérant que ça collera, au risque d'empirer la corruption.

    Pour le reste c'est assez subjectif. A titre personnel j'apprécie en général, comme toi, de transformer tout ou partie de la condition en "safe guard" (if... return, pas de else, ni d'accolades, ni de retours à la ligne) mais c'est un détail. Je n'apprécie pas le second conseil en revanche.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Mai 2016
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2016
    Messages : 313
    Par défaut
    De toute façon, que ce soit à un niveau plus élevé ou dans la fonction, cube=null doit être testé séparément des autres conditions.
    La formulation de pierre-y risque bien de provoquer un plantage si cube est nul, et dans des conditions qui dépendent du compilateur.
    Rien ne garantit que la condition "cube!=null" va être évaluée avant "cube.x>0". Ce code peut s'exécuter avec un compilateur, et planter avec un autre.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    785
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 785
    Par défaut
    A bon? Le compilareur ne garantie pas l'ordre des conditions?

  6. #6
    Membre expérimenté
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Mai 2016
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2016
    Messages : 313
    Par défaut
    Citation Envoyé par pierre-y Voir le message
    A bon? Le compilareur ne garantie pas l'ordre des conditions?
    Non, il n'y a aucune garantie sur l'ordre d'évaluation.
    "if (C1 && C2 && C3)" peut être compilé de différente façons :

    - un compilateur peu optimisé peut décider de calculer C1, C2 et C3 avant d'évaluer C1 && C2 && C3, ce qui provoquerait un plantage de ton code au moment du calcul de C2 si cube est nul.
    - un autre compilateur peut décider d'évaluer C1, et conclure directement que C1 && C2 && C3 est faux si C1 est faux, sans évaluer C2 et C3 => ton code marcherait dans ce cas
    - un autre peut encore évaluer les arguments dans l'ordre inverse, en commençant par C3 et en concluant que C1 && C2 && C3 est faux si C3 est faux, mais l'évaluation de C3 provoquera un plantage de ton code si cube est nul.

    Ta formulation est donc très risquée et non portable, dépendant des optimisations du compilateur. La validité de "cube" doit bien être testée avant.

  7. #7
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par wolinn Voir le message
    Non, il n'y a aucune garantie sur l'ordre d'évaluation.
    Tu as tort, que ce soit en C++, en C# ou vraisemblablement dans n'importe quel autre langage ayant ces opérateurs.

    C++ specification: Unlike the bitwise logic operators, these operators (in their built-in form) do not evaluate the second operand if the result is known after evaluating the first. La spécification est également parfaitement claire sur l'ordre d'évaluation des opérandes et la précédence des opérateurs (de gauche à droite).

    Autrement dit le seconde opérande de && n'est évaluée que si la première était vraie. Si un compilateur violait cette règle, ce serait un bug majeur qui affecterait sévèrement la quasi-totalité des programmes. Inimaginable même pour le dernier des compilateurs.

    Le code suivant est donc parfaitement acceptable :if (item != null && item.x > 0) ...

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    785
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 785
    Par défaut
    A ouf^^, je commençais a plus rien y comprendre.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Mai 2016
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2016
    Messages : 313
    Par défaut
    Soit. C'était un excès de précaution de ma part.
    La norme impose un comportement du compilateur qui n'était pas indispensable (operation commutative, A && B = B && A) et empêche d'éventuelles optimisations de l'ordre d'évaluation dans des cas plus complexes.

  10. #10
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par wolinn Voir le message
    Soit. C'était un excès de précaution de ma part.
    La norme impose un comportement du compilateur qui n'était pas indispensable (operation commutative, A && B = B && A) et empêche d'éventuelles optimisations de l'ordre d'évaluation dans des cas plus complexes.
    Au contraire, la raison même de l'existence de l'opérateur && en plus de & est que le premier conditionne l'évaluation de l'opérande droite à celle de gauche, tandis que le second opérateur évalue toujours les deux opérandes (sauf optimisation inoffensive). Choisir un opérateur plutôt que l'autre c'est préciser l'ordre d'évaluation.

    Ce comportement est donc essentiel.

Discussions similaires

  1. Bonne pratique pour inclure source de projet open source ?
    Par joseph_p dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 05/07/2007, 21h51
  2. Réponses: 5
    Dernier message: 12/09/2006, 18h06
  3. Tutoriel SEO : Introduction et bonnes pratiques pour l'optimisation de pages Web
    Par Community Management dans le forum Référencement
    Réponses: 0
    Dernier message: 06/07/2006, 00h03

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