Blog 4 min de lecture

Découvrez les entrailles de votre projet C++ : étude de cas POCO

Share this article
Découvrez les entrailles de votre projet C++ : étude de cas POCO

Les bibliothèques POCO C++ sont une collection de bibliothèques de classes open source pour développer des applications portables centrées sur le réseau en C++.

POCO signifie POrtable COmponents. Les bibliothèques offrent des fonctionnalités pour les threads, la synchronisation des threads, l'accès au système de fichiers, les flux, les bibliothèques partagées et le chargement de classes, les sockets et les protocoles réseau (HTTP, FTP, SMTP, etc.). Elles incluent également un serveur HTTP, un parseur XML avec interfaces SAX2 et DOM, et l'accès aux bases de données SQL.

La conception et l'implémentation modulaires et efficaces rendent les bibliothèques POCO C++ particulièrement adaptées au développement embarqué.

Jetons un œil à l'intérieur de POCO à l'aide de CppDepend et découvrons quelques faits sur son implémentation et sa conception.

L'implémentation de POCO

Le nombre de lignes de code

Les méthodes comportant de nombreuses lignes de code sont difficiles à comprendre et à maintenir. Cherchons les méthodes de plus de 60 lignes.

Moins de 1 % des méthodes comptent plus de 60 lignes.

La complexité cyclomatique

La complexité cyclomatique est une métrique logicielle procédurale populaire, égale au nombre de décisions pouvant être prises dans une procédure.

Exécutons la requête CQLinq suivante pour détecter les méthodes à refactoriser :

Ainsi, seulement 1 % des méthodes peuvent être considérées comme complexes.

Quelles méthodes sont complexes et insuffisamment documentées ?

Les méthodes avec beaucoup de variables

Les méthodes où NbVariables est supérieur à 8 sont difficiles à comprendre et à maintenir. Les méthodes où NbVariables dépasse 15 sont extrêmement complexes et devraient être scindées en méthodes plus petites (sauf si elles sont générées automatiquement par un outil).

Seulement 8 méthodes ont trop de variables.

Les types avec beaucoup de méthodes et de champs

Seulement 3 % des types ont beaucoup de méthodes.

Et nous pouvons faire la même recherche pour les champs.

Moins de 1 % des types ont beaucoup de champs.

Nous pouvons conclure que POCO est bien implémenté : peu de méthodes sont considérées comme complexes, ses types sont simples et comportent relativement peu de méthodes et de champs, et le code est bien documenté.

LA CONCEPTION

Abstractness vs instability

Le graphe « Abstractness vs Instability » peut être utile pour détecter les projets qui seront difficiles à maintenir ou à faire évoluer. L' article suivant décrit l'utilité de ce graphe et comment l'exploiter pour améliorer la conception.

Pour POCO, voici le graphe « Abstractness vs Instability » :

Seul Foundation se trouve dans la Zone of Pain, ce qui est compréhensible puisqu'il est massivement utilisé par d'autres projets.

L'héritage

L'héritage multiple augmente la complexité et doit donc être utilisé avec prudence.

Cherchons les classes ayant de nombreuses classes de base.

Les rectangles bleus représentent le résultat.

Seules quelques classes dérivent de plus d’une classe.

La cohésion des types

Le principe de responsabilité unique stipule qu'une classe ne devrait pas avoir plus d'une raison de changer. Une telle classe est dite cohésive. Une valeur LCOM élevée désigne généralement une classe peu cohésive. Il existe plusieurs métriques LCOM. LCOM prend ses valeurs dans l'intervalle [0-1]. LCOMHS (HS pour Henderson-Sellers) prend ses valeurs dans l'intervalle [0-2]. Notez que la métrique LCOMHS est souvent considérée comme plus efficace pour détecter les types non cohésifs. Une valeur LCOMHS supérieure à 1 doit être considérée comme alarmante.

Seulement 1 % des types sont considérés comme non cohésifs.

Le couplage efférent

Le couplage efférent d'un type particulier est le nombre de types dont il dépend directement. Les types où TypeCe > 50 dépendent de trop d'autres types. Ils sont complexes et ont plus d'une responsabilité. Ce sont de bons candidats à la refactorisation.

Exécutons la requête CQLinq suivante.

Le résultat est vide : aucune classe n'a donc de nombreuses responsabilités.

Les types les plus utilisés

Il est utile de savoir quels types sont utilisés le plus fréquemment ; pour cela, nous pouvons utiliser la métrique TypeRank.

Les valeurs TypeRank sont calculées en appliquant l'algorithme PageRank de Google au graphe des dépendances entre types. Une homothétie de centre 0,15 est appliquée de sorte que le TypeRank moyen soit de 1.

Les types avec un TypeRank élevé devraient être testés avec plus de soin, car les bugs y sont susceptibles d’être plus catastrophiques.

Cherchons les types à la fois fortement utilisés et complexes.

Le résultat est vide : aucune classe n'est donc à la fois fortement utilisée et complexe.

Le découpage en couches et la métrique Level

Cet article explique la métrique Level et comment l'exploiter pour améliorer la conception.

Cherchons les cycles de dépendances ; pour cela, nous pouvons exécuter la requête CQLinq suivante :

Seules quelques méthodes sont impliquées dans des cycles de dépendances. Prenons le projet Zip comme exemple et regardons son graphe de dépendances.

Un seul cycle de dépendances existe dans ce projet.

En conclusion, POCO est également bien conçu : il est fortement cohésif et faiblement couplé.

Share this article