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 :

Loi de Demeter


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Loi de Demeter
    Salut à toutes et à tous, une belle et heureuse année 2017 !

    Je me pose des questions sur ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    auto forest = simulator.simulate(); 
    assert(forest.at(x0).size() == 1);
    assert(forest.at(x0).at(0)->get_data() == 0);
    Il faut finalement se rappeler que forest a pour type std::map<position_type, std::vector<std::unique_ptr<Tree<Data>>>>

    Je n'aime pas trop le fait d'exposer tous ces détails (preuve en est que j'ai buggé sur les lignes en les relisant). Me confirmez-vous que c'est pas bien (même si c'est surtout des dépendances entre type de la STL) ?

    J'hésite à faire une classe dédiée Forest, mais j'ai toute de même besoin d'effectuer des traitements sur les différentes "couches" d'implémentation (tous les arbres, toutes les données de tous les arbres, les arbres à une position donnée...), et j'ai du coup peur de me perdre en parcourant la Forest (fallait que je la case, désolé ).

    En fait j'ai peur de perdre du temps à dupliquer dans la classe Forest la sémantique qu'on peut attendre d'une map de vecteurs.

    Puis-je avoir votre ressenti ?

    Bien à vous,

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 503
    Par défaut
    J'hésite à faire une classe dédiée Forest
    N'hésites pas, type "STL" bien trop complexe et donnant accès a plein de chose qui n'ont potentiellement aucun sens dans ton cas.
    Tu auras aussi de mettre une API bien plus lisible, ajouter les pré et post condition, etc...

    Tu ne dois pas encore utiliser énormément de primitive de map et de vector, donc change temps tant qu'il est temps.
    Le type "STL", fait en un champ privée et l'implémentation initiale sera écrite en 1 ligne.

    En plus, faire le test de la bascule, c'est 2 minutes.

  3. #3
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour et bonne année.

    A moins que Tree<Data> ait des classes dérivées, tu n'as pas besoin de std::unique_ptr.
    A part ça, un type nu de la forme std::map<Key, std::vector<Value>> peut potentiellement contenir des vecteurs vides. Si on veut imposer comme invariant qu'aucun de ces vecteurs n'est vide, il vaut peut-être mieux encapsuler ce type dans une classe ou choisir un autre type.

    Je propose deux solutions :
    1. Solution rapide mais risquée si on a besoin de changer l'implémentation :
      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
      #ifndef INCLUDE__MY_PROJECT__FOREST__H
      #define INCLUDE__MY_PROJECT__FOREST__H
       
      // ...
      #include <map>
       
      namespace my_project {
       
      typedef std::multimap<position_type, Tree<Data>> Forest;
       
      /*!
       * \file Forest.h
       * \warning Plus tard, la définition du type Forest pourrait avoir une forme proche de :
      \code
       
      class Forest {
      private:
              std::unordered_map<position_type, std::vector<Tree<Data>>> m_data;
      public:
              typedef std::pair<const position_type&, Tree<Data>&> value_type;
              class iterator {
              public:
                      value_type& operator*();
                      // ...
              };
              class const_iterator {
                      // ...
              };
              // ...
      };
       
      \endcode
       * Donc écrivez "Forest" au lieu de "std::multimap<position_type, Tree<Data>>"
       * et ne supposez pas que les éléments sont rangés par ordre croissant des clés.
       */
       
      } // namespace my_project
       
      #endif
    2. Solution un peu plus lente à court terme mais sécurisée : créer une classe Forest. Exemple incomplet :
      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
      #ifndef INCLUDE__MY_PROJECT__FOREST__H
      #define INCLUDE__MY_PROJECT__FOREST__H
       
      // ...
      #include <map>
      #include <vector>
       
      namespace my_project {
       
      class Forest {
      private:
      	/*!
               * \warning "std::map" pourrait être changé plus tard en "std::unordered_map"
               *          ou en "std::unordered_multimap".
               */
      	std::map<position_type, std::vector<Tree<Data>>> m_data;
      public:
      	class iterator {
      	public:
      		Tree<Data>& operator*();
      		// ...
      	};
      	class const_iterator {
      		// ...
      	};
      	iterator begin();
      	iterator end();
      	// ...
      };
       
      } // namespace my_project
       
      #endif

  4. #4
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Merci de vos réponses, direction la forêt !

    Citation Envoyé par Pyramidev Voir le message
    A moins que Tree<Data> ait des classes dérivées, tu n'as pas besoin de std::unique_ptr.
    Mhhh c'est là qu'on va avoir l'occasion de peut-être exploser un de mes choix d'implémentation . Les noeuds de l'arbre ont sémantique d'entité, et lors de la construction de l'arbre, pour éviter d'avoir des soucis (comme un noeud qui serait son propre enfant ou d'avoir des enfants dupliqués), j'ai choisi d'utiliser des std::unique_ptr pour n'avoir qu'une seule représentation du noeud. Du coup pas de souci ( pour l'instant en tout cas, mais vous allez passer par là... ) : si il est déjà dans la topologie on va pas pouvoir le ré-utiliser puisque les insertions de parents ou d'enfants se font seulement par des std::unique_ptr.
    Est-ce que ça se tient ?

    Pour le reste c'est la première fois que je vois des iterators définis à l'intérieur des classes (je me contentais de transférer les itérateurs des membres via une méthode begin() ou end() ), donc je suis en train de faire un peu de doc avant de revenir vers vous

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    On en avait déjà causé. C'est la différence entre le fond et la forme.
    std::map<Key, std::vector<Value>>, c'est la forme de la donnée. Cela concerne les aspects techniques de l'utilisation de la forêt.
    Forest est le fond de ta donnée: sa signification réelle.

    Le code qui se sert de ta forêt n'est normalement intéressé que par sa signification: c'est une forêt.
    Le code concerné par le choix map ou multimap ou autre, c'est le code technique dont dépend le précédent. C'est en fait le code interne de la forêt.

    D'une manière générale, plus que la loi de Demeter, c'est l'essence même de l'abstraction qui résonne là.
    Séparer l'interface significative de l'implémentation technique, c'est, en C++, définir des classes (ou des fonctions).

  6. #6
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Citation Envoyé par ternel Voir le message
    On en avait déjà causé.
    Argh désolé, au temps pour moi, je ne me souvenais pas avoir parlé précisément de ce cas là, maintenant ça me revient. Nos discussions sont si denses en informations que je soupçonne le système d'archivage de mon cerveau d'être totalement dépassé (en voilà un qui gère pas bien ses pointeurs...), surtout si les infos sont orales x)
    Merci pour ton rappel en tout cas

    Le code qui se sert de ta forêt n'est normalement intéressé que par sa signification: c'est une forêt.
    Le code concerné par le choix map ou multimap ou autre, c'est le code technique dont dépend le précédent.
    Evidemment, dit comme ça... de réponse en réponse ma question devient de plus en plus sotte

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

Discussions similaires

  1. Conception : loi de Demeter + ISP
    Par tickyletroll dans le forum C++
    Réponses: 7
    Dernier message: 26/10/2016, 16h05
  2. Que pensez-vous de la loi de Demeter ?
    Par 3DArchi dans le forum Langage
    Réponses: 137
    Dernier message: 03/02/2016, 14h39
  3. La loi de Demeter
    Par shibo dans le forum Langage
    Réponses: 8
    Dernier message: 15/07/2013, 20h47
  4. Loi de demeter / IntelliJ
    Par behess dans le forum ALM
    Réponses: 3
    Dernier message: 24/12/2010, 10h52
  5. Réponses: 3
    Dernier message: 20/07/2009, 13h38

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