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 :

Maintenance de code


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Par d�faut Maintenance de code
    Bonjour,
    J'ai �crit du code et au final, j'ai le sentiment que je peux "mieux faire" pour le rendre maintenable/r�utilisable. Deux illustrations:
    - J'ai une classe "droite" (objet g�om�trique) dans laquelle je fait des calculs (normale de la droite, etc.) mais �galement de l'affichage (OpenGl) avec une m�thode "Draw" de cette classe. Y a-t-il un moyen de dissocier les aspect "g�om�trie" des aspects affichage - par exemple si je souhaite utiliser la classe pour ne faire que des calculs g�om�trique, sans avoir � mettre toute l'artillerie de librairies Open GL dont je ne vais pas me servir ?
    - J'ai une autre m�thode de calcul de courbe (Bezier) ou un "point" de la courbe est d�fini � partir d'autre points de contr�le. Mais ces "points" peuvent �tre soient des valeurs (0.5-1.0-2.3) ou des "points" g�om�triques (avec des coordonn�es). Faut-il utiliser des templates ou un m�canisme d'h�ritage pour faire une classe g�n�rique? O� y a-t-il un autre moyen?
    Merci d'avance pour votre aide.
    Christian

  2. #2
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,
    Citation Envoy� par coberle Voir le message
    Bonjour,
    J'ai �crit du code et au final, j'ai le sentiment que je peux "mieux faire" pour le rendre maintenable/r�utilisable.
    C'est, typiquement, le genre de sentiment auquel il faut etre attentif
    Deux illustrations:
    - J'ai une classe "droite" (objet g�om�trique) dans laquelle je fait des calculs (normale de la droite, etc.) mais �galement de l'affichage (OpenGl) avec une m�thode "Draw" de cette classe. Y a-t-il un moyen de dissocier les aspect "g�om�trie" des aspects affichage - par exemple si je souhaite utiliser la classe pour ne faire que des calculs g�om�trique, sans avoir � mettre toute l'artillerie de librairies Open GL dont je ne vais pas me servir ?
    Oui, il vaut d'ailleurs mieux s�parer la responsabilit� de la partie "m�tier" (calcul etc) de la partie "affichage"

    L'id�al est, tr�s certainement, d'avoir une classe "Drawer" (ou tout autre nom qui indiquerait que sa responsabilit� est le trac� ) qui prendrait ta droite (ou tout autre objet de type "objet g�om�trique" ) en param�tre et qui s'occuperait d'effectuer le tracer sur base d'informations r�cup�r�es depuis la droite

    Les mots qui te seraient tr�s utiles dans ce cas sont visiteur (design pattern), double dispatch et polymoprhisme
    - J'ai une autre m�thode de calcul de courbe (Bezier) ou un "point" de la courbe est d�fini � partir d'autre points de contr�le. Mais ces "points" peuvent �tre soient des valeurs (0.5-1.0-2.3) ou des "points" g�om�triques (avec des coordonn�es). Faut-il utiliser des templates
    La mani�re dont la position d'un point (dans un syst�me) est repr�sent�e s'aparente tr�s clairement � ce que l'on appelle "une politique".

    Tu vas, en effet, utiliser des calculs et des proc�dures diff�rentes pour arriver � positionner un point par rapport aux autres en fonction de la mani�re dont sa position est repr�sent�e, m�me si, au final, tu peux finir par appeler une fonciton comme "position()"

    L'id�al est donc de partir d'une approche g�n�rique, pour ce qui se rapporte � la politique de placement et � ses traits particuliers, en tout cas
    ou un m�canisme d'h�ritage pour faire une classe g�n�rique?
    Il y aura, tr�s certainement, des m�canismes d'h�ritage, voir des m�canismes d'h�ritage avanc�s (une classe non template qui h�rite (sans doute en utilisant le CRTP) d'une classe template, une autre classe template qui h�rite d'une quatri�me classe qui ne l'est pas, ...)

    N'oublie cependant pas que l'h�ritage reste la relation la plus forte qui puisse unir deux classes, et qu'elle se doit donc de respecter un certain nombre de r�gles, potentiellement diff�rentes en fonction de ce qui h�rite de quoi
    O� y a-t-il un autre moyen?
    Il ne faut en tout cas pas mettre une fronti�re trop ferme et d�finitive du genre "je travaille en orient� objet, et j'exclus tout recours au paradigme g�n�rique" ou de son contraire "j'utilise le paradigme g�n�rique et je m'interdit le recours � l'orient� objet"...

    La meilleure mani�re consistera sans doute � m�langer tr�s all�grement les deux de sorte � profiter du meilleur des deux mondes

    Je suis d�sol� d'�tre tellement impr�cis, mais, �tant donn� que tu n'explique ni tes objectifs ni l'existant de mani�re pr�cise, tu ne nous offre pas beaucoup de choix
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Par d�faut
    Merci Koala01 pour ta r�ponse (tr�s) d�taill�e. Etant encore d�butant, les mots de
    visiteur (design pattern), double dispatch et polymoprhisme
    sont encore une peu "abscon". Si tu as des exemple (ou des liens), je suis �videmment preneur.
    Est-ce que ce que tu sugg�res est de cr�er une fonction draw(Objet), o� "Objet" et une droite, un point, une courbe, etc. Dans ce cas, il faudrait que droite, point, courbe etc. soient tous fils/fille de Objet? Comment ensuite "r�cup�rer" le type dans draw de fa�on ce que draw "sache" comment dessiner l'objet ... o� est-ce que je m'�gare?

    Pour ce qui est du 2e point, je ne suis pas certain - � la lecture de ta r�ponse - que ma question �tait tr�s claire. Pour faire simple, imaginons qu'un point P soit d�fini par P(t)=A*t + B(1-t) (o� A et B sont deux autres points et t entre 0 et 1). On voit bien en fait que A et B (et donc P) peuvent �tre des point au sens g�om�trique mais aussi des valeurs (par exemple p(t)=3*t+5*(1-t)). Ce que je souhaite faire est une fonction "g�n�rique" qui permet de calculer Objet_P(t)=Objet_A*t+Objet_B(1-t) o� Objet_A et Objet_B sont soit des valeurs, soit des points et que le type de l'objet P est soit un point, soit une valeur (en fonction du type de A et B).

    Encore merci pour tes conseils.
    Christian

  4. #4
    Membre �m�rite
    Avatar de Ekleog
    Homme Profil pro
    �tudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par d�faut
    Citation Envoy� par coberle Voir le message
    Merci Koala01 pour ta r�ponse (tr�s) d�taill�e. Etant encore d�butant, les mots de sont encore une peu "abscon". Si tu as des exemple (ou des liens), je suis �videmment preneur.
    Google peut t'aider, pour �a.

    Est-ce que ce que tu sugg�res est de cr�er une fonction draw(Objet), o� "Objet" et une droite, un point, une courbe, etc. Dans ce cas, il faudrait que droite, point, courbe etc. soient tous fils/fille de Objet? Comment ensuite "r�cup�rer" le type dans draw de fa�on ce que draw "sache" comment dessiner l'objet ... o� est-ce que je m'�gare?
    Une surcharge, sans prendre en compte ici l'h�ritage, me semblerait plus pratique, et surtout plus dans l'esprit c++ qu'un dispatch � l'ex�cution.

    Pour ce qui est du 2e point, je ne suis pas certain - � la lecture de ta r�ponse - que ma question �tait tr�s claire. Pour faire simple, imaginons qu'un point P soit d�fini par P(t)=A*t + B(1-t) (o� A et B sont deux autres points et t entre 0 et 1). On voit bien en fait que A et B (et donc P) peuvent �tre des point au sens g�om�trique mais aussi des valeurs (par exemple p(t)=3*t+5*(1-t)). Ce que je souhaite faire est une fonction "g�n�rique" qui permet de calculer Objet_P(t)=Objet_A*t+Objet_B(1-t) o� Objet_A et Objet_B sont soit des valeurs, soit des points et que le type de l'objet P est soit un point, soit une valeur (en fonction du type de A et B).
    Comment fais-tu pour multiplier un point par une valeur ?
    Apr�s avoir r�pondu � cette question, tu pourras certainement mieux r�pondre � ta propre question.

    Et, si tu �loignes de l'origine d'un facteur k ((x, y) * k = (x * k, y * k)), alors simplement coder ta "valeur" par un point sur l'axe des r�els peut �tre envisageable.

    Une autre solution pourrait �tre de d�finir P comme :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    template <typename T, typename Objet>
    T P(T const & t, Objet const & objet_a, Objet const & objet_b) {
      return objet_a * t + objet_b * (1 - t);
    }

  5. #5
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Le principe du visiteur est, sommes toutes, relativement simple...

    On peut consid�rer que tu disposes sans doute d'une hi�rarchie d'objets g�om�triques.

    Cette hi�rarchie est � consid�rer comme une hi�rarchie d'objets "visitables" (comprends : qui peut etre visit�e).

    A cot� de cette hi�rarchie, tu aurais un objet "visiteur" dont le role est... de visiter les diff�rentes classes visitables.


    Pour que tous les objets soient visitables, la classe de base se pr�senterait sans doute sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class ObjetGeometrique
    {
        public:
            void accept(Visiteur /* const*/ & ) /* const  */= 0;
    };
    Toutes les classes d�riv�es r�impl�menteraient cette fonction de mani�re � appeler une fonction du visiteur qui se charge de faire le traitement propre � la classe en question:
    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
    class Ligne : public ObjetGeometrique
    {
        public:
            void accept(Visiteur /* const */ & v) /* const*/
            {
                v.visit(*this);
            }
    };
    class Carre : public ObjetGeometrique
    {
        public:
            void accept(Visiteur /* const */ & v) /* const*/
            {
                v.visit(*this);
            }
    };
    class Triangle: public ObjetGeometrique
    {
        public:
            void accept(Visiteur /* const */ & v) /* const*/
            {
                v.visit(*this);
            }
    };
    class Bézier: public ObjetGeometrique
    {
        public:
            void accept(Visiteur /* const */ & v) /* const*/
            {
                v.visit(*this);
            }
    };
    et le visiteur dispose d'une surcharge de la fonction visit pour chaque type particulier d'objet g�om�trique � visiter:
    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
    class Visitor
    {
        public:
            void visit(Ligne /* const */ & l ) /* const
            {
                 /*traitement propre à la ligne */
            } 
            void visit(Carre/* const */ & c) /* const
            {
                 /*traitement propre à la ligne */
            } 
            void visit(Triangle /* const */ & t ) /* const
            {
                 /*traitement propre à la ligne */
            } 
            void visit(Bezier /* const */ & b ) /* const
            {
                 /*traitement propre à la ligne */
            } 
    };
    D�s lors, quand tu vas avoir une collection "d'objet g�om�triques" dans laquelle tu risques de retrouver aussi bien des lignes, des carr�s ou des triangles ou des courbes de b�ziers, et que tu veux traiter "par lots" (comprends : tu veux traiter l'ensemble des �l�ments contenus dans la collection en question), tu pourras travailler sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main()
    {
        std::vector<ObjetGeometrique *> tab;
        /* on remplit tab d'un tas d'objets de type carre, ligne etc... */
        Visiteur v;
        for(std::vector<ObjetGeometrique*>::const_iterator it = tab.begin();
            it!=tab.end(); ++it)
        {
            (*it)->accept(v);
        }
        /* ... */
    }
    En th�orie, c'est g�nial

    En pratique ca l'est aussi... tant que l'on en d�cide pas de transformer la classe Visiteur en hi�rarchie de classes

    En effet, tant que tu n'as qu'un visiteur, il n'y a pas de probl�me:

    Si tu d�cide de rajouter une classe "Rectangle" qui h�rite de ObjetGeometrique, tu n'as qu'� rajouter la surcharge pour cette classe, et tout va pour le mieux.

    Par contre, si tu te dit "oui, mais, le syst�me qui trace mes objets est un visiteur, mais le syst�me qui (... ) l'est aussi, ainsi que celui qui (...) et que celui qui (...) ", tu risques d'�tre tent� de d�river trois, quatre, dix fois (ou plus ) ton visiteur pour prendre en compte chaque type de gestion qui pourrait te venir � l'esprit.

    Le probl�me est alors que tu ne pourras pas envisager de rajouter une classe de type ObjetGeometrique sans passer par tous les visiteurs d�riv�s pour rajouter la surcharge ad-hoc...

    Y compris pour les visiteurs pour lesquels ce genre de surcharge n'a pas lieu d'�tre

    Tout cela pour dire que le principe est g�nial, mais qu'il faut vraiment �tre attentif � ce que l'on fait, et, surtout, � la granularit� des responsabilit�s que l'on va donner � ses classes de bases
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  6. #6
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Citation Envoy� par coberle Voir le message
    - J'ai une autre m�thode de calcul de courbe (Bezier) ou un "point" de la courbe est d�fini � partir d'autre points de contr�le. Mais ces "points" peuvent �tre soient des valeurs (0.5-1.0-2.3) ou des "points" g�om�triques (avec des coordonn�es). Faut-il utiliser des templates ou un m�canisme d'h�ritage pour faire une classe g�n�rique? O� y a-t-il un autre moyen?
    Je n'arrive pas en lisant cette partie � savoir de quel c�t� de la fronti�re tu te situe. Quelle fronti�re ? Celle entre l'interface et l'impl�mentation.

    Est-ce que tu veux que tes points soient repr�sent�s en interne de mani�re variable, ou est-ce que tu veux que bien qu'utilisant une repr�sentation unique, ils puissent �tre manipul�s par des m�thodes diff�rentes.

    Le second cas a a priori ma pr�f�rence, pour des raisons de simplicit�s. Tu choisis une bonne fois pour toute la repr�sentation (par exemple, deux coordonn�es cart�siennes), et tu fournis les moyens de cr�er des points dans cette repr�sentation en fonction de tes besoins :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    Point Bezier::getPointAtCurvilinearAbscissa(double u);
    Point getCenterOfGravity(vector<pair<Point, double>> weightedPoints);
    ...
    Dans le premier cas, tu vas devoir impl�menter les diff�rents modes de repr�sentation (et en plus les passages d'un mode � l'autre). Quel serait l'int�r�t ? Simplement si certains algorithmes peuvent s'impl�menter de mani�re diff�rente dans un mode ou dans un autre, il peut �tre int�ressant de ne pas perdre de l'information en passant dans une repr�sentation unique.

    Si tel est ton cas, se pose la question de comment quand m�me g�rer de mani�re unifi�e diff�rentes classes de points aux repr�sentation diff�rente (je dis unifi�e, pas unique. Par exemple avec des fonctions aux interfaces identiques, mais aux impl�mentation tirant �ventuellement partie des sp�cificit�s des repr�sentations). C'est ce que l'on nomme le polymorphisme.

    Et dans ce cas, deux classes de polymorphisme sont potentiellement bien adapt�es, qui se repr�sentent en C++ par l'h�ritage+fonctions virtuelles, ou par les templates.

    H�ritage + fonction virtuelles, c'est adapt� si tu vas m�langer des points aux repr�sentations diff�rentes, par exemple appeler le m�me algorithme � tous les points d'un tableau, mais chaque point de ce tableau peut avoir sa propre repr�sentation, qui �ventuellement n'est pas connue � la compilation du programme (par exemple, lue dans un fichier). Inconv�nients : �a va t'obliger � passer par des pointeurs (lourdeur d'�criture, risques de fausses manip, co�ts d'utilisation) et le choix entre les diff�rents algo se fera lors de l'ex�cution (co�t runtime).

    Templates, c'est adapt� si tu veux �crire des algorithmes haut niveau qui puissent �tre utilis� avec diff�rent modes de repr�sentation, mais qu'au moment de l'appel des ces algorithmes, dans un programme particulier, on sait quel mode de repr�sentation sera utilis�. C'est bien pour faire des biblioth�ques r�utilisables dans diff�rents contextes. Le choix des algos bas niveaux finalement utilis�s aura lieu totalement � la compilation (gratuit au runtime). On ne manipule pas de pointeurs. On gagne en perfs ce qu'on perd en flexibilit�.

    Mais n'oublie pas : Il y a des chances que dans ce cas, une seule repr�sentation mais des moyens de cr�ation multiple soit la bonne solution... Ne pas faire de l'overdesign.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  7. #7
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Par d�faut
    Merci � tous pour vos r�ponses d�taill�es - je crois que j'ai � "manger" pour plusieurs jours :-).
    Quelques commentaires/pr�cisions:
    - Ekleog
    Comment fais-tu pour multiplier un point par une valeur ?
    -> Je multiplie chaque coordonn�e du point
    - LolyLoic
    Je n'arrive pas en lisant cette partie � savoir de quel c�t� de la fronti�re tu te situe. Quelle fronti�re ? Celle entre l'interface et l'impl�mentation.
    -> "les deux mon g�n�ral".
    Au final, les avis que vous donnez sont tr�s instructifs et montrent que, pour un probl�me donn�, il n'y a pas de solutions unique (d'une certaine fa�on, tant mieux, sinon on ne serait pas l� :-))
    Encore merci ! Je vais essayer de r�fl�chir � tout �a et mettre en musique.
    Christian

Discussions similaires

  1. Faut-il commenter son code source pour le rendre plus lisible et maintenable ?
    Par mayayu dans le forum D�bats sur le d�veloppement - Le Best Of
    R�ponses: 149
    Dernier message: 09/11/2009, 02h30
  2. le C++ "moderne" et la maintenance de code
    Par yan dans le forum C++
    R�ponses: 21
    Dernier message: 22/08/2009, 17h42
  3. [DW MX2004] Maintenance de Code HTML commun
    Par codenstock dans le forum Dreamweaver
    R�ponses: 1
    Dernier message: 14/09/2007, 22h30
  4. l'astuce date et heure de maintenant sans formule ni code
    Par zazaraign�e dans le forum Contribuez
    R�ponses: 5
    Dernier message: 14/08/2007, 13h54

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