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 :

problème de modélisation


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut problème de modélisation
    Bonjour à tous,
    J'ai un problème de modélisation: mon but (pour illustrer mon problème) est de modéliser les déplacements quotidiens d'une population de personnes à travers le réseau routier et ferroviaire d'une agglomération. J'ai donc deux classes (il m'en faudrait plus pour le problème ci dessus mais je vais me focaliser sur ces deux là): une classe personne et une classe train. Chaque personne dispose de la liste des trains quelle peut emprunter pour arriver à son travail. Je voudrais maintenant modéliser la possible suppression d'un train et un principe de notification (un peu comme il se pratique lors de grève avec l'envoi de sms par la sncf) aux usagés (ou client c'est comme vous voulez). Actuellement, j'ai tendance à procéder de la manière suivante:
    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
     
    class Personne
    {
      std::set<Train*> trainsPossibles;
     
    public:
     
      ~Personne()
      {
        BOOST_FOREACH(Train* t, trainsPossibles)
          t->remove(*this);
      }
     
      void add(Train& t)
      {
        if (trainsPossibles.find(&t) != trainsPossibles.end())
          return;
        trainsPossibles.insert(&t);
        t.add(*this);
      }
     
      void remove(Train& t)
      {
        if (trainsPossibles.find(&t) == trainsPossibles.end())
          return;
        trainsPossibles.erase(&t);
        t.remove(*this);
      }
    };
     
    class Train
    {
      std::set<Personne*> personnesCandidates;
     
    public:
     
      ~Train()
      {
        BOOST_FOREACH(Personne* p, personnesCandidates)
          p->remove(*this);
      }
     
      void add(Personne& p)
      {
        if (personnesCandidates.find(&p) != personnesCandidates.end())
          return;
        personnesCandidates.insert(&p);
        p.add(*this);
      }
     
      void remove(Personne& p)
      {
        if (personnesCandidates.find(&p) == personnesCandidates.end())
          return;
        personnesCandidates.erase(&p);
        p.remove(*this);
      }
    };
    Je vous ai mis ici les méthodes principales permettant de gérer la mise à jour des trains candidats d'une personne lors de la suppression d'un train. Alors voilà, ça marche mais il faut reconnaitre que le risque de ne pas mettre à jour correctement les listes des personnes ou des trains n'est pas forcément négligeable; de plus cette modélisation impose un couplage fort entre les personnes et les trains (il me parrait cohérent qu'une personne connaisse la liste des trains quelle peut emprunter par contre il me parait beaucoup plus douteux qu'un train ait connaissance des ses possible passagers). Enfin dernier point "négatif", cette modélisation fait usage de pointeurs "bruts" qui sont assez décriés ici. Donc voilà je voulais savoir si vous aviez une idée pour palier aux problèmes que je viens d'évoquer et donc de permettre un couplage moins fort et si possible sans utilisation de pointeurs "bruts". Merci à vous.

  2. #2
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    A mon sens, une personne ne connait pas des trains mais des numéro de lignes. La différence : probablement que le n° de ligne pour un usage n'est pas plus qu'un identifiant abstrait. S'il a besoin d'un service spécifique sur un train, alors il doit disposer d'une interface qui lui fourni un train en fonction du numéro de ligne qu'il demande. Ce qui permettrait de découpler ton usager de la classe train.
    Ensuite, tu m'a l'air d'être typiquement dans le cas du pattern Observateur. Découple les deux classes en mettant en œuvre ce pattern.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Merci 3DArchi pour ta réponse. Pour tout vous dire en fait cette question était un prétexte détourné pour entamer la discussion autour des relations entre objets qui me hantent régulièrement.
    Le design pattern observer/observable est un exemple assez parlant de mon dilemme: son implémentation proposée par David fait intervenir des listes de pointeurs "bruts" ce qui auparavant ne me dérangeait pas du tout mais à la vue des nombreux messages sur ce forum mettant en garde l'utilisation des pointeurs bruts, j'en étais arrivé à me demander s'il n'y avait pas d'autre moyen de procéder puisqu'à priori plus personne en C++ "moderne" ne se servait de ces bon vieux pointeurs (depuis l'avènement des nombreuses versions des smart-pointers).
    Alors là, j'avoue que je suis un peu perdu: je ne vois absolument pas comment on peut mettre en place une relation entre classes de type 1/plusieurs ou plusieurs/plusieurs sans ces fameux pointeurs "bruts" (jusqu'à présent je n'ai pas trouvé les smart-pointers très utiles puisque dans la plupart des cas que j'ai eu à gérer, la relation n'implique pas un lien dans la durée de vie des objets, la seule condition étant que si un objet de la relation est détruit, il ne doit plus être référencés par l'autre partie de la relation).
    En faisant de nombreuses recherche (bon, peut être pas si nombreuse que ça mais bref) je suis tombé sur http://web.univ-pau.fr/~belloir/SOURCE/These.html avec notamment ce projet http://web.univ-pau.fr/~belloir/DOC/...rapportTER.pdf ce qui me fait dire que je ne suis pas le seul à me poser des questions mais qu'en même temps, on est pas très nombreux. Alors j'avoue que j'ai pas lu en détails la thèse et la proposition d'implémentation en C++ des relations tout ou partie (j'essaierai de m'y mettre ce week-end) mais si vous avez des échos sur ces travaux ou un explication sur le fait que pas tant de monde que ça se pose ces questions, je suis preneur
    Tout témoignage est le bien venu!

  4. #4
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Perso, pour implémenter le pattern observer, j'utilise assez souvent les signal/slots de boots, et je ne gère pas de pointeur explicitement.

    Autrement, je ne vois pas trop où est le problème avec des smart pointers. A priori, les trains ne possèdent pas leurs observateurs. Les passagers ne possèdent pas les trains. Donc je verrai bien dans les deux cas des weak_ptr, en supposant par ailleurs que les trains et passagers sont gérés par shared_ptrs.
    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.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Mince alors! Je savais bien que j'aurais dû étudier depuis longtemps plus en détails les smart pointers!

    Ce qui me gênait dans les smart pointers c'est que je ne connaissait que le shared_ptr (pas précisément celui de boost) et donc toute "référence" maintenait en vie l'objet "pointé". Mais bon à priori, il faut quand même faire des if(shared_ptr<int> r = q.lock()) à chaque fois que l'on veut accéder à la ressource (c'est juste histoire de dire, je suis déjà carrément satisfait de cette approche!).

    Si j'ai bien compris, dans mon exemple précédent, j'ai juste à ajouter une méthode clean qui me permet de "nettoyer" la liste des trains d'une personne (en bouclant sur les trains et en supprimant ceux pour lesquels shared_ptr<int> r = q.lock() échoue) et je n'aurais plus qu'à appeler cette méthode en début de toute méthode accédant aux trains de la personne (par exemple si j'ai une qui permet de choisir un train)

    Sinon je vais jeter un coup d'oeil aux signal/slot de boost (ils faisaient déjà parti de ma to read list avec également les libs d'ASL) ce week-end.
    Merci encore pour vos réponses bonne soirée à tous

  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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    Si j'ai bien compris, dans mon exemple précédent, j'ai juste à ajouter une méthode clean qui me permet de "nettoyer" la liste des trains d'une personne (en bouclant sur les trains et en supprimant ceux pour lesquels shared_ptr<int> r = q.lock() échoue) et je n'aurais plus qu'à appeler cette méthode en début de toute méthode accédant aux trains de la personne (par exemple si j'ai une qui permet de choisir un train)
    En faisant attention que cette méthode ne garanti pas dans un environnement mutlithread que les pointeurs restant sont bien vivants (c'est ce genre de considération qui fait passer par un shared_ptr afin de maintenir en vie l'objet le temps qu'on travaille avec).
    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.

Discussions similaires

  1. problème de modélisation dimensionnelle (hiérarchie)
    Par kince dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 07/04/2007, 09h48
  2. Problème de modélisation avec Case Studio
    Par soso78 dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 15/06/2006, 18h13
  3. Problème de modélisation
    Par Tyler Durden dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 10/06/2006, 16h18
  4. [Class/PHP/Postgres] Problème de modélisation...
    Par k-reen dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 27/02/2003, 08h49

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