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

C++ Discussion :

le C++ "moderne" et la maintenance de code


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut le C++ "moderne" et la maintenance de code
    Bonjour suite à cette discutions :
    http://www.developpez.net/forums/d79...lacant-switch/
    je créé ce poste pour avoir vos avis. Mon problème est assez simple. J'ai une structure composée de int et string. Je dois pouvoir trier un vecteur en fonction de n'importe quels membres. Un point important, c'est un vecteur utilisé pour de l'ihm et qui sera trié de temps en temps par l'utilisateur. Voulant optimiser un minimum, ma première version est très lourde à relire et donc autant plus complexe à maintenir (d'où mon poste au départ):

    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
    switch(m_sortFlag)
        {
            case DESCENDINGORDER | IDMAILBOX:
                qStableSort 
                        (
                            m_internal.begin(),
                            m_internal.end(),
                            std::binary_negate<compareIdMailBox>(compareIdMailBox()) 
                        );
     
                break;
            case ASCENDINGORDER | IDMAILBOX:
                qStableSort 
                        (
                            m_internal.begin(),
                            m_internal.end(),
                            compareIdMailBox() 
                        );
     
                break;
     
            case DESCENDINGORDER | IDEMAIL:
               qStableSort 
                        (
                            m_internal.begin(),
                            m_internal.end(),
                            std::binary_negate<compareIdEmail>(compareIdEmail()) 
                        ); 
                break;
            case  ASCENDINGORDER | IDEMAIL:
               qStableSort 
                        (
                            m_internal.begin(),
                            m_internal.end(),
                            compareIdEmail() 
                        ); 
                break;
    ...
    }
    fcharton m'as proposé une solution, que je trouve bien plus pertinente par rapport à mon problème. Un simple prédicat avec un paramètre dans le constructeur qui contiendra le switch.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Sorter {
    private:
      int SortType;
    public:
      Sorter(int st) : SortType(st) {}
      bool operator()(type &t1,type &t2) { 
        switch SortType {
           case ... : return...
        }
      }
    };


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    qStableSort (v.begin(),v.end,Sorter(sorttype));
    Comparéau code de départ, ce trie sera moins rapide, car le switch sera présent à chaque itération, mais faux problème, car le trie dépend du temps "humain" et donc bien assez rapide pour une iHM et donc un humain. Et surtout, la lisibilité du code et sa maintenance y gagne considérable!
    Comme il est toujours intéressant de confronter les idées,

    Êtes vous d'accord avec ce raisonnement? ou trouvez vous cela absurde?
    Ou
    Dans quelle mesure le C++ moderne peut rend la maintenance plus facile?


  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Quel rapport avec "C++ moderne blablabla" ?
    La solution 2 est à jeter selon moi. La première est simplement pas terrible parce que c'est pas bien factorisé.

    Sinon pourquoi ne pas plutôt maintenir des indexes que de tout trier à chaque fois...

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par loufoque Voir le message
    La solution 2 est à jeter selon moi
    pourquoi? Du moment qu'il est suffisamment rapide pour une IHM?

    La première est simplement pas terrible parce que c'est pas bien factorisé.
    Tu ferais comment?

    Citation Envoyé par loufoque Voir le message
    Sinon pourquoi ne pas plutôt maintenir des indexes que de tout trier à chaque fois...
    Tu veut dire dire des tableaux d'index?
    Ben à chaque nouveaux items ou modif d'un item, il faudra maintenir à jours tous les tableaux. Si tu rajoute un nouveau paramètre, faut rajouter un tableau d'index. Pour la personne qui va écrire le code, il devrais si retrouver. Mais pour le gas qui va reprendre le code?

    Ou tu parle d'un truc comme boost.Multi-index?

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    pourquoi? Du moment qu'il est suffisamment rapide pour une IHM?
    Parce que ça n'a pas de sens.
    Le choix du membre s'effectue avant, ce n'est pas une partie de l'état du critère de comparaison.

    Tu ferais comment?
    Une solution simple est de faire une table qui associe identifiieur du champ au critère de comparaison associé.

    Tu veut dire dire des tableaux d'index?
    Non, je veux dire des indexes. Comme dans un livre.

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Une solution simple est de faire une table qui associe identifiieur du champ au critère de comparaison associé.
    Tu veut dire une sorte de tableau de prédicat/fonction?

  6. #6
    Membre très actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par défaut
    La méthode 2 ne me semble pas bonne du tout. Elle ne fait que décaler le "problème" à un autre endroit (le switch) tout en étant plus pénalisante en terme d'opérations effectuées.

    Je suis d'accord avec loufoque pour un système de lookup

    Pourquoi pas un truc dans ce genre ?
    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
     
    template<typename T, typename R = bool>
    struct sorter
    {
      enum pred {
        box_asc = 0 //ASCENDINGORDER | IDMAILBOX
       ,box_desc    //DESCENDINGORDER | IDMAILBOX
       //,..
      };
     
      typedef std::tr1::function<R (T, T)> pred_type;
     
      static pred_type table[];
    };
     
    template<typename T, typename R>
    typename sorter<T, R>::pred_type sorter<T,R>::table[]
    = {
      compareIdMailBox()
     ,std::binary_negate<compareIdMailBox>(compareIdMailBox())
      //,..
    };
     
     
    typedef sorter<int> sortint;
     
    //int m_flag = sortint::box_desc;
     
    std::stable_sort(m_internal.begin(), m_internal.end(), sortint::table[m_flag]);

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par loufoque Voir le message
    ce n'est pas une partie de l'état du critère de comparaison.
    Pourquoi? Si tu considères que ton critère compare des objets, le sens et la nature de la comparaison en sont des paramètres, qui représentent des états. Si tu dois faire pas mal de ces comparaisons (dans des tris, mais aussi lors de recherches ou d'affichages) et si les critères utilisés dépendent d'élements complexes, tu auras intéret à les centraliser (c'est un peu ce que tu ferais avec une table, remarque).

    Citation Envoyé par loufoque Voir le message
    Une solution simple est de faire une table qui associe identifiieur du champ au critère de comparaison associé.
    Ca, ca ne va fonctionner que si les critères sont peu nombreux... Suppose maintenant qu'ils puissent se combiner entre eux : tu vas trier ta table dans un ordre, puis selon plusieurs critères, et éventuellement en fonction de modes de calculs différents (paramètres d'affichage du champ, en valeur, en %, en indice, disons), ta table va vite devenir importante.

    Le lien aux "champs", je me méfierais... Très vite, tu vas te retrouver avec des champs calculés, totaux, évolution, taille du document, message, fichier, et là...

    Citation Envoyé par loufoque Voir le message
    Non, je veux dire des indexes. Comme dans un livre.
    Pareil, ca marche si ton tableau est petit (parce qu'il faut garder ces index en mémoire), et si on ne le recalcule pas (sinon il faut tout garder à jour). Les index, c'est bien si tu as peu de colonnes, ou si tu utilises toujours les mêmes. Ce n'est pas incompatible avec les approches précédentes, soit dit en passant : on stocke les index dans le conteneur d'origine, à cote des objets, et on programme leur utilisation dans la fonction de tri.

    Ce que j'essaie de dire, c'est qu'il est utile de centraliser le code de comparaison, parce que c'est typiquement le genre de chose qui a tendance à se compliquer assez vite de sous cas, et de cas particulier. C'est d'ailleurs l'approche suivie par les grid fournies dans la plupart des IHM : pour trier une colonne, on appelle une fonction de comparaison de lignes, paramètrable pas la colonne de tri et un certain nb d'élements supplémentaires... Il y a une raison à cela.

    Personnellement, une table me va tout aussi bien qu'un foncteur. Je trouve juste l'approche foncteur plus propre (même si moins efficace): une table, faut la créer, la gérer, la détruire.

    @metagoto : remplacer un switch par une énum, c'est un peu de la triche, non? (et puis, surtout, une énum c'est monodimensionnel, ca va te sauter à la figure très vite, ca...)

    Francois

  8. #8
    Membre très actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par défaut
    Citation Envoyé par fcharton Voir le message
    @metagoto : remplacer un switch par une énum, c'est un peu de la triche, non? (et puis, surtout, une énum c'est monodimensionnel, ca va te sauter à la figure très vite, ca...)
    Je ne sais pas, c'est le truc le plus simple auquel j'ai pensé pour "nommer" les index de lookup
    Après, je ne fais que proposer..
    Je viens de tester, ça compile et ça fonctionne (je sais, ce n'est pas un critère en soi). Si ça n'avait pas été le cas, je l'aurai précisé aussi!

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