Accueil/Docs/Graphes & dépendances/Graphe de dépendances

Graphe de dépendances

Décrypter la complexité du code avec le graphe de dépendances CppDepend

CppDepend offre un large éventail de fonctionnalités pour aider les utilisateurs à explorer une architecture de code existante via des graphes de dépendances interactifs, des matrices de structure de dépendances et des possibilités de requêtes de code.

Vidéo de démarrage (3 min)

Grâce à la collaboration de :

  • Un graphe de dépendances interactif
  • Une Dependency Structure Matrix
  • Possibilités de requêtes de code interactives
  • Menus disponibles dans les menus contextuels de la fenêtre de l'éditeur de code Visual Studio
  • Menus disponibles dans les menus contextuels de l'Explorateur de solutions Visual Studio

...CppDepend offre un large éventail de fonctionnalités pour aider l'utilisateur à explorer une architecture de code existante. Dans cet article, vous apprendrez comment tirer parti de ces fonctionnalités pour réaliser les scénarios d'exploration de code les plus courants.

Graphe de dépendances

Par défaut, le panneau du graphe de dépendances CppDepend affiche le graphe des dépendances entre projets :

graphe des dépendances entre projets

Vous pouvez choisir un projet, et via le menu clic droit, CppDepend propose d'explorer le graphe des dépendances entre namespaces.

graphe des dépendances entre espaces de noms

Et pour chaque namespace, CppDepend propose d'explorer le graphe des dépendances entre les types d'un namespace.

graphe des dépendances entre les types d'un namespace

Et via le menu clic droit, CppDepend propose d'explorer le graphe des dépendances entre les membres (méthodes + champs) d'un type.

graphe des dépendances entre membres

Haut de page

Call Graph

CppDepend peut générer tout graphe d'appels dont vous pourriez avoir besoin en deux étapes.

  • D’abord : Demande les appelants/appelés directs et indirects d'un type, d'un champ, d'une méthode, d'un namespace ou d'un projet. L'effet est que la requête CQLinq suivante est générée pour correspondre à tous les appelants ou appelés demandés.graphe d’appelNotez que, dans le résultat de la requête CQLinq, la métrique DepthOfIsUsing/DepthOfIsUsedBy montre la profondeur d'utilisation (1 signifie direct, 2 signifie via un utilisateur direct, etc...). La requête CQLinq peut facilement être modifiée pour ne correspondre qu'aux appelants/appelés indirects avec une certaine condition sur la profondeur d'utilisation. Notez également que les appelants/appelés demandés ne sont pas nécessairement du même type que l'élément de code concerné. Par exemple, ici nous demandons les méthodes qui utilisent directement ou indirectement un type.
  • Deuxièmement : Une fois que la requête CQLinq correspond à l'ensemble des appelants/appelés souhaité par l'utilisateur, l'ensemble des résultats peut être exporté vers le graphe de dépendances. Cela a pour effet d'afficher le graphe d'appels souhaité.graphe d’appel

Haut de page

Graphe d’héritage de classes

Pour afficher un graphe de classes d'héritage, la même procédure en deux étapes présentée dans la section précédente (sur la génération d'un graphe d'appels) doit être appliquée.

  • D’abord : Génère une requête CQLinq demandant l'ensemble des classes qui héritent d'une classe particulière (ou qui implémentent une interface particulière). Ici, la requête CQLinq suivante est générée :hérite
  • Deuxièmement : Exportez le résultat de la requête CQLinq vers le graphe de dépendances pour afficher le graphe d'héritage souhaité.hérite

Haut de page

Graphe de couplage

Il peut être nécessaire de savoir exactement quels éléments de code sont impliqués dans une dépendance particulière. Surtout lorsqu'on doit anticiper l'impact d'un changement structurel. Dans la capture d'écran ci-dessous, le panneau Info de CppDepend décrit un couplage entre 2 projets.

En pointant une cellule dans la matrice de dépendances, cela indique que X types d'un projet A utilisent Y types d'un projet B. Remarquez que vous pouvez changer l'option Poids sur cellule à # méthodes, # membres ou # espaces de noms, si vous avez besoin de connaître le couplage avec autre chose que des types.

couplage 1

Un simple clic gauche sur la cellule de la matrice affiche le graphe de couplage ci-dessous.

couplage 2

Un graphe de couplage peut aussi être généré à partir d'une arête du graphe de dépendances. Ici, vous pouvez ajuster l'option Épaisseur des arêtes vers autre chose que # type.

couplage 3

Haut de page

Graphe de chemins

Si vous souhaitez explorer un chemin ou un cycle de dépendances entre 2 éléments de code, la première chose à faire est d'afficher la matrice de dépendances avec l'option Poids sur cellules : Profondeur d’utilisation directe & indirecte.

Les cellules bleues et vertes de la matrice représentent chemins tandis que les cellules noires représenteront cycles de dépendances Par exemple, ici, le panneau Info nous indique qu'il existe un chemin de longueur minimale 7 entre les 2 types impliqués.

chemin 1

Un simple clic gauche sur la cellule affiche le graphe de chemin ci-dessous.

chemin 2

Haut de page

Graphe de tous les chemins

Dans certaines situations, vous devrez connaître tous les chemins d'un élément de code A vers un élément de code B. Par exemple, ici, le panneau Info nous indique qu'il existe un chemin de longueur minimale 2 entre les 2 types impliqués.

tous chemins 1tous chemins 2

Enfin, exporter vers le graphe les 12 types correspondant à la requête CQLinq montre tous les chemins de A à B.

tous chemins 3

Haut de page

Graphe de cycles

Comme nous l'avons expliqué dans la section précédente, pour traiter les graphes de cycles de dépendances, la première chose à faire est d'afficher la matrice de dépendances avec l'option Poids sur cellules : Profondeur d’utilisation directe & indirecte. Les cellules noires représentent alors des cycles.

Par exemple, ici, le panneau Info nous indique qu'il existe un cycle de dépendances de longueur minimale 5 entre les 2 types impliqués.

cycle de dépendances 1

Un simple clic gauche sur la cellule affiche le graphe de cycle ci-dessous.

cycle de dépendances 2

Nous tenons à vous avertir que l'obtention d'un cycle de dépendances « arrondi » propre comme celui illustré ci-dessus est en réalité plus une situation exceptionnelle qu'une règle.

Souvent, l'affichage d'un cycle aboutit à un graphe non 'arrondi' comme celui montré ci-dessous. Dans cet exemple, la longueur minimale d'un cycle entre les 2 types impliqués (en jaune) est 12. Comptez le nombre d'arêtes traversées d'un type jaune à l'autre, et vous obtiendrez 12. Vous verrez que certaines arêtes seront comptées plus d'une fois.

cycle de dépendances 3

Haut de page

Grand graphe visualisé avec la Dependency Structure Matrix

Ici, nous aimerions souligner le fait que lorsque le graphe de dépendances devient illisible, il vaut la peine de passer à la matrice de dépendances.

Le graphe de dépendances et la matrice de dépendances coexistent car :

  • Le graphe de dépendances est intuitif mais devient illisible dès qu'il y a trop d'arêtes entre les nœuds.
  • La matrice de dépendances demande du temps pour être comprise, mais une fois maîtrisée, vous verrez que la matrice de dépendances est bien plus efficace que le graphe de dépendances pour explorer une architecture existante.

Plus d'informations sur la lisibilité de la matrice de dépendances dans Identifier les motifs de structure du code d’un coup d’œil

Pour illustrer le propos, voici ci-dessous les mêmes dépendances entre 77 namespaces, représentées par le graphe de dépendances et la matrice de dépendances.

grand graphegrande matrice

Haut de page

Essayez CppDepend aujourd'hui

Commencez votre essai gratuit de 14 jours avec accès complet à toutes les fonctionnalités de documentation. Sans carte bancaire.