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 :

Communication entre les objets


Sujet :

C++

  1. #1
    Membre averti
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut Communication entre les objets
    Bonjour

    Lorsque je programme, je me pose régulièrement la même question lorsque je réfléchis à l'organisation de mes classes.

    Je me demande souvent par exemple comment faire communiquer mes classes entre elles ?

    Par exemple dans le cadre d'un programme de simulation. Si j'ai une classe Affichage qui s'occupe de la gestion de l'affichage à l'écran (OpenGL) et une classe Simulation qui s'occupe de calculer les états de la simulation. Lorsque la classe Simulation calcule les nouveaux paramètres de la simulation, elle a besoin d'en informer la classe Affichage (certaines variables de la classe d'affichage doivent être mises à jour pour le prochain affichage). Mais dans ce cas, comment gérer la communication entre les deux classes.

    On pourrait par exemple passer à la classe Simulation un pointeur sur l'instance de la classe Affichage. De cette façon, la classe simulation peut modifier elle même les valeurs de la classe affichage.

    On pourrait aussi instanciée la classe Simulation à l'intérieur de la classe Affichage.

    Je n'arrive donc pas à voir comment gérer la communication de manière PROPRE. Je voudrais donc savoir ce qu'il est conseillé de faire dans ce genre de situation. En effet, c'est un problème que je rencontre régulièrement.

    Deuxièmement, je me pose une autre question à propos des classes que l'on instancie une seule fois dans le programme. Par exemple dans l'exemple précédent, on utilisera une seule instance de la classe Affichage. Je voudrais savoir s'il est préférable de créer une seule instance de cette classe (Affichage affichage = new Affichage() ) ou bien d'utiliser cette classe de manière statique (en déclarant toutes ces méthodes statiques) ?

    Merci d'avance de m'aider un peu. Ce serait vraiment sympa.
    Salutations.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je dirais une seule instance de Affichage, typiquement suivant le pattern Singleton.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut
    Donc, pour l'exemple de simulation que j'ai cité, on pourrait faire que les classes Affichage et Simulation soient des singletons (car elle ne seront créés qu'une seule fois dans le programme) et toutes les autres classes sont des classes normales (par exemple un classe Voiture pour une simulation de course automobile). Ne risque-t-on pas d'avoir trop de classes singleton ?

    Est-ce que quelqu'un aurait une suggestion à propos de mon premier problème qui concerne la manière de communiquer entre deux classes ?

  4. #4
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Citation Envoyé par Dani3L Voir le message
    Donc, pour l'exemple de simulation que j'ai cité, on pourrait faire que les classes Affichage et Simulation soient des singletons (car elle ne seront créés qu'une seule fois dans le programme) et toutes les autres classes sont des classes normales (par exemple un classe Voiture pour une simulation de course automobile). Ne risque-t-on pas d'avoir trop de classes singleton ?
    En quoi serait-ce un problème ?

    De manière plus générale, la structure de ton programme permet aussi d'éviter d'avoir plein de singletons. Par exemple si seule ta classe Affichage (qui est déjà un Singleton) a besoin d'une instance de Simulation, mais qu'aucune autre n'a besoin de récupérer un pointeur (ou une référence dessus), pas la peine de faire de Simulation un Singleton.

    Citation Envoyé par Dani3L Voir le message
    Est-ce que quelqu'un aurait une suggestion à propos de mon premier problème qui concerne la manière de communiquer entre deux classes ?
    Plusieurs solutions, et une à mon avis à éviter à tout prix : il ne faut pas que ta classe Simulation dépende directement de Affichage, ton modèle doit rester indépendant de la vue. Donc première chose à faire, créer une interface pour l'affichage. Ensuite soit tu décides de créer la simulation depuis la classe Affichage qui s'enregistrera au près de la Simulation, soit tu externalises la construction (dans un builder par exemple) qui sera chargé d'instancier ce qu'il faut et de passer les différentes références/pointeurs comme il faut.

  5. #5
    Membre averti
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut
    Citation Envoyé par bolhrak Voir le message
    Plusieurs solutions, et une à mon avis à éviter à tout prix : il ne faut pas que ta classe Simulation dépende directement de Affichage, ton modèle doit rester indépendant de la vue. Donc première chose à faire, créer une interface pour l'affichage. Ensuite soit tu décides de créer la simulation depuis la classe Affichage qui s'enregistrera au près de la Simulation, soit tu externalises la construction (dans un builder par exemple) qui sera chargé d'instancier ce qu'il faut et de passer les différentes références/pointeurs comme il faut.
    Donc si j'ai bien compris, une bonne solution serait d'instancier les deux classes Affichage et Simulation à l'extérieur de celles-ci et de créer une interface dans la classe Affichage (des méthodes publics bien choisies) et de passer un pointeur sur l'instance d'Affichage à l'instance de la classe Simulation. De cette façon lorsque la classe Simulation a besoin de modifier quelque chose lié à l'affichage, elle le fait en passant par l'interface de la classe Affichage.

    De plus concernant les classes singletons, il est préférable de créer des classes singletons que d'avoir des classes "statiques" (classes dont les méthodes sont statiques et que l'on utilise sans instanciation).

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    L'interface n'est pas créée "dans" la classe affichage, je faisais plutôt référence à l'héritage. La classe Simulation manipulera un objet de type AffichageInterface par exemple, sans savoir qu'il s'agit en fait d'un objet de type Affichage.

    Et oui pour les singletons.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Je te conseillerais volontiers de réfléchir correctement aux responsabilités de chaque classe.

    Selon moi, ce n'est pas la classe Simulation qui doit demander à la classe Affichage de faire son travail, mais c'est bien à la classe Affichage de demander à la classe Simulation si... elle a des objets à afficher

    En effet, l'ordre logique dans lequel les choses pourrait se faire est fort proche de
    1. Créer un environnement de simulation
    2. Créer les objets nécessaire à la simulation (*)
    3. réglages des conditions de simulation (vitesse, particularités de l'environnement telles que gravité, état des routes, température, ...)
    4. Lancer l'affichage de la simulation (**)

    (*) peut se faire aussi bien avant qu'après le réglage des conditions de simulation
    (**)Soit le premier affichage lance la simulation (la classe Affichage lance elle-même un message "start" à la simulation), soit la simulation est lancée avant d'être transmise pour affichage... au choix.

    La classe Affichage obtenant un pointeur vers l'instance de Simulation qu'il va devoir gérer et bouclant (une fois la simulation lancée) sur un principe proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Tant que simulation non finie
        Obtenir Collection Objets de simulation
        Pour chaque Objet dans Collection
            Afficher Objet
        Fin Pour
    Fin Tant
    De son coté, la simulation doit
    • pouvoir répondre aux messages (en ne considérant que ceux que la classe Affichage va lui envoyer)
      • As-tu fini - ou quel est ton état (non débuté/ en cours/ fini)
      • Donne moi ta collection d'objets
      • éventuellement Vas-y (démarre la simulation)
    • exposer les comportement
      • d'ajout d'objets à la simulation
      • de réglage des conditions de simulation
    • disposer de comportements qu'elle garde bien pour elle qui consistent à
      • agir sur les objets qu'elle gère
      • supprimer les objets arrivés "en fin de vie" (voitures "hors course" ou éléments morts, par exemple )

    Au final, on se rend compte que la classe Affichage doit disposer de la classe Simulation, mais pas l'inverse
    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

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Concernant les singletons les avis sont partagés, personnellement je fais partie de ceux qui les haïssent au plus haut point essentiellement parce qu'ils sont une grosse gène pour effectuer des tests unitaires et gérer les dépendances entre composants correctement.
    Et comme on peut toujours faire sans, autant en profiter. D'expérience à la longue ça n'a que des avantages...

    MAT.

  9. #9
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Normalement, la simulation ne devrait pas avoir connaissance de l'affichage, elle ne devrait même pas se préoccuper de savoir s'il y en a une ou pas.

    Le problème que tu as peut typiquement être résolu par une architecture s'inspirant du pattern MVC (Modèle Vue Controleur), tu devrais facilement trouver des informations en cherchant un peu.
    L'idée principale, c'est d'utiliser le pattern Observateur : l'objet Simulation sait qu'il est observé, sans se soucier de ce qu'effectuent les objets qui l'observe. Dès qu'une modification "intéressante" a lieu, il prévient tous les observateurs qu'il a été modifié, et c'est tout. Ensuite, libre à chacun des observateurs (en l'occurence, ton objet Affichage) de venir récupérer les informations nouvelles. De cette façon, on découple l'aspect métier/calcul/simulation de l'aspect interface, et on permet d'ajouter ultérieurement de nouveaux observateurs (un logger par exemple) sans avoir besoin de changer quoi que ce soit dans le code.

    Les explications que je t'ai donné sont assez générales, mais comme je le disais précédemment, tu n'auras aucun mal à trouver de la documentation sur cette solution.

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Au final, on se rend compte que la classe Affichage doit disposer de la classe Simulation, mais pas l'inverse
    En général (MVC, pattern observateur, ...) c'est pourtant la vue qui observe le modèle, et donc la simulation qui notifie l'affichage.

    A mon avis c'est une vision très procédurale de faire l'inverse, ça oblige à coller plein d'accesseurs sur la simulation pour questionner son état, et ça donne un flux d'exécution qui n'arrête pas de faire des aller-retours entre affichage et simulation.
    Alors que si la simulation se contente de balancer des notifications vers un observateur, le flux d'exécution est toujours dans le même sens et le découplage entre les deux se fait plus naturellement : un bon vieux pattern observateur et zou !

    MAT.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    En général (MVC, pattern observateur, ...) c'est pourtant la vue qui observe le modèle, et donc la simulation qui notifie l'affichage.

    A mon avis c'est une vision très procédurale de faire l'inverse, ça oblige à coller plein d'accesseurs sur la simulation pour questionner son état, et ça donne un flux d'exécution qui n'arrête pas de faire des aller-retours entre affichage et simulation.
    Alors que si la simulation se contente de balancer des notifications vers un observateur, le flux d'exécution est toujours dans le même sens et le découplage entre les deux se fait plus naturellement : un bon vieux pattern observateur et zou !

    MAT.
    J'admets mon erreur sans problème, mais il semblerait que l'on oublie quelque chose d'important:

    La simulation n'est pas forcément le modèle

    Car, tout le monde a oublié qu'une simulation utilise... une collection d'objets (même s'il ne doit y en avoir qu'un), et que ce sont ces objets qui "ont leur propre vie" que l'on observe dans les circonstances propres à la simulation

    En cela, étant donné que c'est la simulation qui "dicte les règles", elle fait bien plus office de contrôleur, d'autant plus qu'elle doit discuter dans les deux sens, avec les différents objets qu'elle met en oeuvre.

    Tu devra donc toujours prévoir une certaine forme de communication dans les deux sens

    D'un coté, on peut simplifier la communication en faisant en sorte que ce soit la simulation qui envoie le signal de fin à l'affichage ou concernant certains contextes/états, tout à fait d'accord, mais, d'un autre côté, il faudra toujours prévoir un moyen quelconque pour l'affichage de retrouver les objets mis en œuvre par la simulation, et les informations qui permettent de les afficher...
    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

  12. #12
    Membre averti
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut
    Je ne comprends toujours pas vraiment comment implémenter concrètement ceci. En effet, Si l'on a par exemple une collection de classes Voiture qui sont des objets nécessaire à la simulation. Où faut-il stocker ces instances de Voiture ? Dans la classe Simulation ? Mais dans ce cas la classe Affichage a également besoin d'accéder à ces objets Voiture pour pouvoir les afficher ? Comment la classe Simulation peut-elle uniquement avertir la classe Affichage de mettre à jour l'affichage ?

    Ce que je ne comprends pas trop c'est étant donné les trois classes Affichage, Simulation et Voiture c'est où on créer ces instances ? qui s'occupe de les stocker ? et comment faire communiquer tout ceci ensemble ?

  13. #13
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Tu devra donc toujours prévoir une certaine forme de communication dans les deux sens
    Oui c'est vrai, je me suis aperçu de ça en relisant depuis le début...
    En fait tout dépend de ce qu'on met dans Affichage et Simulation.
    Si ce sont de gros blocs fonctionnels qui coupent juste en deux toute une application, y'a en effet clairement des liens dans les deux sens.

    Je réagis toujours promptement sur ce sujet parce qu'à mon sens une notion centrale dans le dessein orienté objet est la distinction entre push et pull (c'est mentionné dans le GoF au chapitre de l'observateur d'ailleurs).
    Soit lorsqu'on a besoin d'informations on les demande à un autre composant (donc pull) soit on est juste passif et on attend de recevoir les informations (donc push).
    Je suis un fervant partisan du push à outrance, pour moi c'est la seule manière d'obtenir des systèmes qui se décomposent bien et peuvent ensuite être remaniés facilement.

    En général on a été formés pour réfléchir en pull, c'est la fameuse méthode qui consiste à découper un problème en sous-problèmes élémentaires puis à résoudre itérativement chacun de ces sous-problèmes, ce qui se traduit en général par : getMachin() puis getTruc() et getBidule(), et enfin je calcule chose à partir de machin, truc et bidule pour résoudre le problème initial.
    En plus les deux mécanismes se marient souvent assez mal, il faut retourner tout le code un peu comme une chaussette pour passer de l'un à l'autre...

    http://c2.com/cgi/wiki?HollywoodPrinciple

    Mais je m'égare...

    MAT.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    @Mat007>>Nous sommes donc bien d'accord, et j'allais d'ailleurs admettre de mon coté qu'il fallait voir ce que l'on entend par "affichage"

    A vrai dire, Dani, comme l'a fait remarquer Mat007, il faudrait que nous en sachions plus sur la manière dont tu envisage l'affichage, et la manière dont tu envisage le fonctionnement de ta simulation.

    Ainsi, le modèle observateur pourrait très bien fonctionner si:
    1. tu n'envisage l'affichage que comme une sortie "texte" ou en tout cas fort proche
    2. tu veux que ta classe simulation prenne la responsabilité de demander l'affichage

    Je m'explique:
    Imaginons, pour l'exemple, que tu te contente d'un affichage intermitant sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Affichage::doAffich(const Contexte& con, const set<Objet*>& obj)
    {
        cout<<"Résultat après iteration numero"<<con.it<<" de la simulation:"<<endl;
        for(std::list<Objet*>::const_iterator it=obj.begin();it!=obj.end();++it)
            cout<<(*it)->statut()<<endl;
    }
    et que tu parte sur le principe de une itération de la simulation==>un affichage.

    Tu peux tout à fait envisager une classe Simulation prenant la forme de
    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
     
    class Affichage;
    typedef std::set<Affichage*> AfficSet;
    class Objet;
    typedef std::set<Objet*> ObjetSet;
    class Simulation
    {
        public:
            Simulation(){}
            /* virtual*/ ~Simulation(){}
            /* comme on part sur le pattern Observateur */
            void registerAffichage(Affichage* toadd)
            {
                if(setaff.find(toadd)==setaff.end())
                    setaff.insert(toadd)
            }
            void unRegisterAffichage(Affichage* torem)
            {
                if(setaff.find(torem)!=setaff.end())
                    setaff.erase(torem);
            }
            /* et comme il faut gérer une collection d'objets */
            void addObjet(Objet* toadd)
            {
                if(setobj.find(toadd)==setobj.end())
                    setobj.insert(toadd)
            }
            void removeObjet(Objet* torem)
            {
                if(setobj.find(torem)!=setobj.end())
                    setobj.erase(torem);
            }
            void performSimulation()
            {
                while(!context.finished)
                {
                     /* tu demande à tous les objets de réagir au contexte acutel */
                     for(ObjetSet::iterator it=setobj.begin();it!=obj.end();++it)
                         (*it).doSomething(context);
                     /* tu demande à tous les affichages de faire leur boulot
                      * (cela correspond à la méthode update que l'on rencontre
                      * dans l'énoncé du principe de l'observateur ;) 
                      */
                     for(AffichSet::iterator it=setaff.begin();it != setaff.end();++it)
                         (*it)->doAffich(context,setobj);
                }
            }
        private:
            Context context;//tout ce qui permet de savoir où en est la simulation
            AffichSet setaff;//tous les observateurs dérivés de la classe Affichage
            ObjetSet setobj;//tous les objets servant à la simulation
    };
    Pour être tout à fait correct, il faut indiquer que Simulation prend plutôt la forme d'un médiateur, pour la cause , mais bon...

    Par contre, si tu prévois un affichage de type "tracé" en boucle (en utilisant, par exemple, une bibliothèque 2D ou 3D), il va falloir envisager les choses autrement:

    Tu peux toujours prévoir une méthode update qui permet de changer le contexte dans ta classe Affichage, qui sera appelée par ta classe Simulation, pour indiquer le contexte actuel, mais le contexte ne sert plus que de "condition de fin d'affichage"

    Et tu finis donc par un algorithme tel que je l'ai présenté plus haut dans lequel tu te sert du contexte pour évaluer la condition que j'avais nommée simulation non finie

    [EDIT]Ceci dit, dans ce cas là, je préfèrerais honnêtement que la classe Simulation propose une méthode estFinie() qui sera appelée par la classe Affichage, justement dans le but d'éviter que la classe Affichage aie une référnce sur la classe Simulation qui elle-même a ... une référence sur la classe Affichage

    De cette manière, ce sera toujours la même classe qui pose des questions à l'autre, et l'autre ne doit jamais s'occuper d'envoyer un message à la première

    J'ai conscience, Mat, que cela rend la dépendance de la classe Affichage plus forte vis à vis de la classe Simulation et que cela implique de rajouter des méthodes supplémentaire, mais je maintiens que cela reste plus "propre" à l'usage
    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

  15. #15
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Pour moi, la classe Simulation ne doit s'occuper que de l'initialisation du "monde" qui va être simulé, du déroulement du temps (itérations, échéancier d'évènements...) et de la libération des ressources.

    Comme koala01 le fait remarquer, le simulateur n'est pas le modèle. Je créerais donc une classe Monde, ou Course, ou que sais-je, afin de contenir l'ensemble des véhicules et toutes les informations décrivant le système à simuler. Ensuite, ça dépend un peu du type de simulation : SMA (Simulation Multi-Agents), simulation à évènements discrets, simulation continue... Cependant, dans chacun des cas de figure, la logique dynamique est contenue dans le modèle, ce sont les objets, ou le monde, qui savent quelle va être leur évolution, et pas le simulateur, ni l'affichage.

    De mon point de vue, le modèle n'a pas besoin de (et ne devrait pas !) connaître ni le simulateur, ni l'affichage. Ensuite, le simulateur possède forcément une référence vers le modèle, pour pouvoir l'initialiser, invoquer les actions qui le feront évoluer et le "nettoyer". L'affichage peut avoir connaissance du simulateur s'il est interactif (s'il permet de configurer, démarrer, arrêter la simulation).

    Enfin, pour ce qui est de la mise à jour de l'affichage, j'aurais envie de rester sur l'idée de l'Observateur, on enregistre l'affichage auprès du modèle qui le notifie dès qu'une donnée change (en lui envoyant éventuellement les données, la méthode push dont parlais Mat007). Cependant, cette solution a malheureusement le désavantage de devoir placer des notifications un peu partout dans le modèle, tandis que la méthode proposée par koala01, dans laquelle c'est le simulateur qui prévient l'affichage a chaque fois qu'il fait évoluer le modèle, a le mérite d'être simple et de limiter la mise à jour de l'affichage à un simple appel de méthode à chaque itération.

  16. #16
    Membre averti
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut
    En tous cas merci beaucoup pour vos réponses. Je comprends mieux les différents choix qui s'offrent à moi. Je vais essayer de mixer un peu les différentes propositions.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Je me permet de remonter le sujet pour réagir à
    Citation Envoyé par stillman Voir le message
    Pour moi, la classe Simulation ne doit s'occuper que de l'initialisation du "monde" qui va être simulé, du déroulement du temps (itérations, échéancier d'évènements...) et de la libération des ressources.

    Comme koala01 le fait remarquer, le simulateur n'est pas le modèle. Je créerais donc une classe Monde, ou Course, ou que sais-je, afin de contenir l'ensemble des véhicules et toutes les informations décrivant le système à simuler. Ensuite, ça dépend un peu du type de simulation : SMA (Simulation Multi-Agents), simulation à évènements discrets, simulation continue... Cependant, dans chacun des cas de figure, la logique dynamique est contenue dans le modèle, ce sont les objets, ou le monde, qui savent quelle va être leur évolution, et pas le simulateur, ni l'affichage.
    Je suis d'accord avec toi, si on se place du seul point de vue de la conception.

    Le fait de rajouter une classe "monde" qui s'occuperait de gérer les "circonstances" (comprend: les objets de la simulation et toutes les données qui ont une influence sur la manière dont ils peuvent réagir) indication de temps ou de durée serait plus en accord avec le principe de la délégation des responsabilités, et "relèguerait" la classe Simulation à mi-chemin entre la vue et le contrôleur.

    La simulation aurait alors - entre autres - pour responsabilité de gérer le monde dans la durée.

    Cependant, d'un pur point de vue de l'implémentation et de l'ordre logique d'exécution, je me pose réellement des questions sur l'opportunité et la pertinence d'augmenter la complexité de la chose en ajoutant cette classe.

    En effet, l'ordre logique d'exécution est que la création du "monde" et les modifications de circonstances passent toutes par... la simulation.

    En outre, le "monde" ne trouve son intérêt plein et entier... qu'au travers de la simulation, et ne doit - sous réserve de spécification contraire - pas survivre à la simulation qui l'a mis en œuvre.

    Nous devrions donc de toutes manières exposer dans la simulation toutes les méthodes permettant de gérer les circonstances du "monde".

    Mais, d'un autre côté, il n'est pas sémantiquement correct de dire que la simulation est un "monde", et on ne peut donc pas envisager l'héritage.

    Nous sommes donc, du point de vue de la conception, dans un contexte de composition.

    Et là, nous sommes en droit de penser au problème de la voiture et du moteur:

    Il n'y a que de rares cas dans lesquels le moteur est susceptible d'être considéré comme une entité à part (si l'application est destinée à une usine de montage ou à un garagiste, par exemple)...

    Pour "le commun", les informations relatives au moteur peuvent se résumer à son couple, sa puissance, sa cylindrée, son carburant et le nombre de vitesses, et il reste cohérent de ce point de vue de placer ces informations dans la classe "voiture", sans passer par une classe "moteur".

    En définitive, si je ne rejette pas l'idée de créer une classe "monde", j'ai envie de dire YAGNI, parce que je suis partisan de la solution la plus simple en toutes circonstances.

    Si, à l'usage, il apparait que cette classe "monde" s'avère nécessaire pour une chose à laquelle nous n'avons pas pensé, il sera toujours temps de sortir les circonstances de la simulation pour en faire une classe séparée et autonome
    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

  18. #18
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Citation Envoyé par koala01 Voir le message
    En définitive, si je ne rejette pas l'idée de créer une classe "monde", j'ai envie de dire YAGNI, parce que je suis partisan de la solution la plus simple en toutes circonstances.
    C'est vrai que j'ai parfois tendance à me compliquer la vie, à trop vouloir faire dans la généricité et l'extensibilité ! La patternite me guette...

  19. #19
    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
    Tu enregistres ton acteur en donnant un identifiant et un callback à appeler quand on reçoit un message, et voilà. Ensuite tu peux envoyer un message vers cet identifiant.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Tu enregistres ton acteur en donnant un identifiant et un callback à appeler quand on reçoit un message, et voilà. Ensuite tu peux envoyer un message vers cet identifiant.
    oui... bien sur...

    Et pour peu que les différentes méthodes de gestion prennent un nombre ou des types d'arguments différents, je ne doute pas que tu me sortira un truc très beau et très efficace à base de template avec un soupçon de boost ou de pattern factory ou de n'importe quoi dans le genre...

    Et, effectivement: c'est faisable... Mais je n'ai jamais dit que ce n'était pas faisable (d'ailleurs, "mon métier est de vous dire que tout est possible" ).

    Je reconnais en outre les avantages de le faire du point de vue de la "belle conception" ni de ceux de la réutilisabilité ou de l'évolutivité du code fournis...

    Mais la question n'est pas de savoir si c'est faisable, mais bel et bien de savoir si, en l'état actuel des choses, il est opportun et cohérent de le faire eut égard à la complexité que cela engendrera immanquablement.
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JSF] Communication entre les beans
    Par Arnaud Giuliani dans le forum JSF
    Réponses: 1
    Dernier message: 01/06/2006, 23h07
  2. Communication entre les vues
    Par beb30 dans le forum MFC
    Réponses: 3
    Dernier message: 18/04/2006, 15h01
  3. Réponses: 3
    Dernier message: 22/11/2005, 11h12
  4. [visual C++/Matlab] communication entre les deux
    Par Bilouzzz dans le forum MFC
    Réponses: 2
    Dernier message: 15/10/2005, 05h05
  5. GLScene et les collisions entre les objets
    Par HopeLeaves dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 13/06/2005, 19h45

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