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

  1. #21
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    De toute façon soit ton comportement peut suivre un schéma identique avec des points de variations précis, soit il est complètement différent. Dans les deux cas, tu auras à implémenter ces variations même si elles ne sont instanciées qu'une fois.
    Le pattern Decorateur permet de cumuler/remplacer des comportements et c'est en ce sens qu'il peut éviter la multiplicité des classes .... sauf si tous les comportement n'ont rien en commun.
    Je crois qu'il faudrait un peu plus d'éléments contextuels de ton application pour mieux cerner ton besoin. Car l'approche jusqu'à présent était essentiellement autour du langage alors que visiblement c'est à la base un problème d'architecture.

  2. #22
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Re,

    ...soit il est complètement différent...sauf si tous les comportement n'ont rien en commun...
    C'est le cas. En réalité, il serait plus juste de dire que ces comportements sont "imprévisibles", parce qu'il seront définis par l'utilisateur.

    Je crois qu'il faudrait un peu plus d'éléments contextuels de ton application pour mieux cerner ton besoin
    Plus qu'un long discour encore une foi, je te donne un bout de code qui représente bien la manière dont "tout ça" devrait fonctionner chez l'utilisateur.

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
     
    void load();
    void checkEvents(std::vector<any> &, const int);
    void do_something(std::vector<any> &, const int);
    void do_other(std::vector<any> &, const int);
     
    Object obj1, obj2;
     
    int main()
    {
        load();
     
        while(OK)
        {
            obj1.draw(obj1.param);
            obj2.draw(obj2.param);
        }
     
        //...
     
        obj1 -= do_something; //A Partir de maintenant, ne fera plus 
        //do_something() quand il sera dessiné
     
        while(!OK)
        {
            obj1.draw(obj1.param);
        }
    return 0;
    }
     
    void load()  //Permet de configurer l'objet (points, etc...)
    {
        std::vector<Point> vect; //Vecteur temporaire qui contient les points
        vect.push_back(Point(0,0,0));
        vect.push_back(Point(0,0,1));
        //...
        //associe un ensemble de points et une couleur
        obj1.push_back(Color(255,255,0,255),vect);
     
        vect.erase();
        vect.push_back(Point(1,0,0));
        vect.push_back(Point(0,1,0));
        //...
        obj1.push_back(Color(0,255,255,255),vect);
     
        obj1.draw_mode = MODE1;
        obj1.onDraw += checkEvents; //Ajoute un pointeur sur une fonction dans un attribut de obj1.
        //Ces fonctions seront éxécutées à cahque fois que la méthode "Object::draw(std::vector<any> &)" est appelée
        obj1.push_param(Point(0,0,0)); //Ajoute un point dans le conteneur Object::param contenant des "any" 
        //(il sera en fait automatiquement lu par la 1ère fonction)
     
        obj1.onDraw += do_something;
        obj1.push_param(Type_A(/*...*/)); //Lu automatiquement par la 2ème fonction
     
       //.........
     
        obj2.onDraw() += do_other;
        obj2.push_param(Type_B());
     
    }
     
    void checkEvents(std::vector<any> & v_param, const int i) 
    //Ici, besoin d'un paramètre "origine" que l'on retrouverait a chaque foi
    //et qui appartiendrait à un objet, ou justement qui pourrait ne pas lui appartenir 
    //
    //Le paramètre i qui est passé ici représente le numéro de la fonction, dans l'ordre des ajouts
    {
        Point *origine = any_cast<Point>(v_param[i]); //On a besoin du paramètre associé à cette fonction
        //Ca pourrait facilement ce généraliser (cad plusieurs paramètres associés à une fonction)
        //notamment en passant un std::vector<int> plutôt qu'un int, mais je n'y ai pas encore 
        //bien réfléchi et je ne sais pas la forme exacte que ça peut prendre
     
     
        if(LEFT)
        {
            (*origine).X -= 2;
            translate(*origine);
        }
    }
     
    void do_something(std::vector<any> & v_param, const int i)
    //Ici besoin d'un autre parametre à conserver tout au long de l'existence de l'objet, 
    //mais "inatendu", cad je ne savait pas que l'utilisateur allait définir un type "Type_A"
    {
        Type_A *monParam = any_cast<Type_A>(v_param[i]);
        _do_something(monParam);
    }
    Pour résumer : l'utilisateur ajoute des fonctions qu'il aura définies et qui seront éxécutées à chaque dessin. Ces fonctions ont besoins de paramètres sur l'objet à traiter, et qui devront être conservées tout au long de l'existence de l'objet.

    Et toute la question est : comment conserver ces paramètres, qui sont en qque sorte des attributs de l'objet, mais "indéfinis".
    De cette manière (std::vector<any>) je trouve assez simple la "communication" entre les fonctions définies par l'utilisateurs (qu'il aura préalablement enregistrées), et mes Object...

    Sachant que si il a besoin d'un paramètre récurent, il peut très bien faire hériter une nouvelle classe de Object.
    Ces paramètres ont un caractère unique à chaque objet (à chaque instance de Object) car rien ne me dit que un Object obj2 utiliserai les mêmes fonctions pour "onDraw". Ces fontions n'auraient donc pas besoin des même paramètres. Et rien ne me dit non plus que je me serve plus d'une fois d'un obj'x', et de ses fonctionnalités.

    Voila ou j'en suis actuellement (penser que le paramètre "any" est la manière la plus pratique de résoudre la chose).

    Juste pour info, la classe Object telle qu'elle devrait être définie :
    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
     
    class Object
    {
        std::vector<Fptr> onDraw; //Fptr est une classe que j'ai définie et qui implémente des pointeurs
        //sur un certain type de fonction.
     
        std::vector<any> param; //Mon fameux conteneur de paramètres "any"
     
        std::vector<std::pair<Color, std::vector<Point> > > point_set; //Mes points à dessiner
     
    publc:
        MODE draw_mode;
     
        Object();
        virtual ~Object();
     
        virtual void draw(std::vector<any> &);
        virtual void push_back(Color &, sd::vector<Point> &);
        virtual void push_param(any &);
     
        //...
     
    };
    Donc la tu en sais autant que moi sur ce que je veux faire
    Tu en pense quoi ?

    Merci d'avance pour tes conseils, en espérant m'être mieux fait comprendre

    A+

  3. #23
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    De toute façon, les dites fonctions tu DOIS les définir. Ce que tu as, c'est une méthode Draw qui appelle une fonction PARTICULIERE, et qui a besoin pour se faire d'argument PARTICULIER !

    Je verrais en gros un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class Drawable{
      std::vector<std::pair<...> points;
    public:
      retourtype Draw(argtype arg);
      virtual Drawable* deleteSomethingSpecial(const std::string& reco); // UN NVI ici ne ferai peut-être pas de mal au passage
    private:
      virtual retourtype doSomethingSpecial(argtype arg);  
    };
    Après quoi, tu as serieusement besoin d'un pattern décorateur pour doSomethingSpecial.

    Bon, a moins de faire du D, faudra sacrifié l'écriture obj -= doSomething.
    Pour en enlevé, j'aurai bien aimé surchargé delete, mais ça se fait pas trop. Du coup, il va falloir que tu fasse une méthode supplémentaire.

    L'avantage, c'est que pour ajouter des comportement, tu fera :
    obj = new comportement(obj,parametre);
    Et "paramêtre" seront défini dans ton décorateur. Cela t'evitera des ennuie >< !

    Bien sur, comme c'est un décorateur, les comportements hérite de Drawable. Cf le tuto plus haut.

  4. #24
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Comme je suis généreux aujourd'hui, voilà un code un peu plus développé :

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    class Drawable {
      std::vector<std::pair<Color, std::vector<Point> > > point_set;
     
    private:
      virtual void vDraw();
      virtual void doSomethingSpecial() {};
      virtual Drawable* vDeleteSomethingSpecial(const std::string& reco) {return this};
    public:
      Drawable* deleteSomethingSpecial(const std::string& reco){
        //assert(precondition);
        return vDeleteSomethingSpecial(reco);
      }
      void draw() {
        doSomethingSpecial();
        vDraw();
      }
      virtual ~Drawable();
    };
     
    void Drawable::vDraw() {
      //...
    }
     
    Drawable::~Drawable() {
      //...
    }
     
    //*******************//
     
    class SpecialDrawable : Drawable{
    protected:
       Drawable* base;
    private:
       virtual bool isThis(const std::string& reco) = 0;
    protected;
       virtual void vDraw() { /*Can be final */
         base->draw();
       }
       virtual Drawable* vDeleteSomethingSpecial(const std::string& reco) {/* Can be final */
          if(isThis(reco)) {
             Drawable* ret = base;
             base = 0;
             delete this;
             return ret;
          }
          base = base->deleteSomethingSpecial(reco);
          return *this;
       }
    public:
       SpecialDrawable(Drawable* _base): base(_base) {}
       virtual ~SpecialDrawable {
          delete base;
       }
    };
     
    //*****************************//
     
    class DoSomethingGreat : SpecialDrawable {
       type name;
    private:
      virtual void doSomethingSpecial();
      virtual void isThis(const std::string& reco) {
         return (reco == string("DoSomethingGreat");
      }
    public:
      DoSomethingGreat(Drawable* _base, std::vector<boost::any> arg);
      virtual ~DoSomethingGreat();
    };
     
    void DoSomethingGreat::doSomethingSpecial() {
      //...
    }
    DoSomethingGreat::DoSomethingGreat(Drawable* _base, std::vector<boost::any> arg) : SpecialDrawable(_base) {
      //...
    }
    DoSomethingGreat::~DoSomethingGreat(){
      //...
    }
    Bon, c'est écris à la volée, et sans editeur approprié. Il doit y avoir 15k fautes de syntaxes. Mais la sémentique est là. Je sais pas ce qu'en pense les autres, mais j'ai l'impression que c'est ce que tu veux >< !

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/03/2013, 20h46
  2. Réponses: 1
    Dernier message: 14/06/2011, 18h02
  3. Réponses: 5
    Dernier message: 05/02/2009, 16h20
  4. Réponses: 14
    Dernier message: 13/07/2007, 12h05
  5. Type structure en param d'une fonction
    Par totoche dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 28/02/2007, 14h26

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