
Je vais d'abord décrire brièvement toutes les sections principales du livre avec mes petits commentaires. Ensuite, je rédigerai une conclusion générale avec les avantages et les inconvénients du livre. Spoiler : le livre est excellent, et ses avantages l'emportent largement sur ses défauts.
Les bases du développement logiciel
Cette partie du livre est entièrement consacrée aux notions de base de la programmation, à la structure de celle-ci et à ce qu’englobe le développement logiciel. Elle traite des étapes telles que la définition des exigences, le développement, les tests et la maintenance. Bien sûr, ces étapes sont décrites de manière plus détaillée et intéressante, donc la lecture n'est pas ennuyeuse. Cependant, cette section sera surtout utile à ceux qui débutent leur carrière de programmeur. Pour une meilleure compréhension, des métaphores et analogies sont utilisées dans les chapitres (par exemple, une analogie avec la construction). Comme dans beaucoup de livres similaires, on y mentionne également le coût des erreurs selon les étapes de création du logiciel (de manière superficielle ici, mais plus en détail plus loin). Un autre point positif : cette section mentionne déjà que les approches de développement peuvent varier : itératives (spirales) et en cascade. Les avantages et inconvénients de chaque approche sont brièvement décrits. Les termes et approches plus modernes comme Scrum ou Agile ne sont pas abordés ici, mais les méthodologies mentionnées par l’auteur suffisent amplement pour un débutant. Enfin, l’auteur aborde aussi des caractéristiques importantes que doit posséder un logiciel, telles que : la scalabilité, la maintenabilité, la portabilité, la tolérance aux pannes, la sécurité, et d'autres encore.
Code de haute qualité
Si vous pensez qu’après ce long mais intéressant contenu vous allez directement plonger dans la section sur l’écriture de code génial et les débats houleux sur le nommage des fonctions, des variables, ou l’usage des tabulations et des espaces, vous vous trompez. Vient ensuite une section entière sur la conception logicielle. Je ne dirais pas qu'il s'agit d’architecture à part entière — comme l'architecture en oignon (dans le cas des monolithes) ou celle des microservices. Il s’agit plutôt ici de décrire le système globalement, d’identifier de gros modules, puis de concevoir des classes distinctes, décrites ensuite sous forme de méthodes. C’est une sorte de programmation abstraite avec l'utilisation de diagrammes et de schémas. Je ne garantirais pas qu'aujourd'hui cette approche (diagrammes et schémas) soit utilisée partout. Personnellement, je ne l’ai rencontrée qu’au collège et à l’université. Dans aucun de mes emplois, ni mes amis ni mes collègues n’ont dessiné de schémas. Cette section est aussi basée sur la POO, ce qui peut ne pas être aussi simple pour la programmation fonctionnelle. Ainsi, cette partie est intéressante à lire, mais son application pratique reste discutable.
Ici, il s’agit plutôt de résoudre de petites et moyennes tâches que de gérer des projets complets. Aucune mention des technologies, usage généralisé des abstractions et respect des principes SOLID. D’ailleurs, l’approche POO est expliquée assez correctement. Bien sûr, on pourrait lire un livre entier à ce sujet, mais pour les débutants, c’est suffisant. Pas mal de temps est aussi consacré au bon nommage des classes et des méthodes. L’auteur explique quand il est pertinent de créer des méthodes séparées et quand ce n’est pas nécessaire. Il parle aussi brièvement des exceptions et de la gestion des erreurs. Un autre plus intéressant pour les débutants est la programmation avec du pseudocode. Je l’appelle souvent la programmation « sur papier ». Cela sera particulièrement utile pour ceux qui ne savent pas encore comment écrire complètement tel ou tel algorithme.
Variables
À partir de cette section, je recommanderais de lire le livre attentivement à tous les programmeurs, même à ceux qui ont déjà plusieurs projets à leur actif et plusieurs années d’expérience.
C’est une centaine de pages de contenu. On pourrait se demander : que peut-on bien dire sur les variables ? En réalité, beaucoup de choses utiles. La section commence par un test intéressant sur la connaissance des types de données (y compris les arbres, les tas et autres). Des exemples de bonne et mauvaise initialisation des variables dans différents langages sont présentés. Les portées des variables sont expliquées avec des illustrations claires. Des conseils généraux pour minimiser la portée sont donnés.
Le chapitre aborde aussi la durée de vie des données, le nommage des variables temporaires, des statuts (commutateurs), ainsi que les conventions de nommage selon les langages. On y discute des abréviations courantes et acceptées, des préfixes standards et des bonnes pratiques pour raccourcir les noms.
Vers la fin de la section, une étude plus détaillée des types de données et de leurs limitations est proposée : nombres à virgule flottante, énumérations, constantes, types personnalisés, tableaux, structures, pointeurs.
Opérateurs
Cette partie du livre traite de l'organisation séquentielle du code, de l’utilisation des opérateurs conditionnels et des boucles. Cette section compte aussi une centaine de pages, donc il y a de quoi approfondir. Par exemple, une comparaison détaillée est faite entre la construction et le fonctionnement (en termes de durée et de performance) des mêmes boucles dans différents langages : C, C++, C#, Java et Visual Basic. Les sujets de la récursion et du goto sont également abordés.
Amélioration du code
Cette section est composée des chapitres suivants :
- Qualité du logiciel
- Construction collaborative
- Tests réalisés par les développeurs
- Débogage
- Refactoring
- Stratégies d’optimisation du code
- Méthodes d’optimisation du code
On y retrouve au début les exigences et caractéristiques du logiciel, similaires à celles mentionnées au début. Le coût de détection et de correction des défauts est évoqué. Cette section est globalement théorique, avec peu de code. Le pair programming est mentionné. Comme je l’ai déjà noté dans la première section, certains éléments sont un peu discutables car un peu datés. Les tests sont abordés. D’ailleurs, je prépare prochainement une critique sur un livre dédié aux tests. Mais contrairement aux livres classiques qui enseignent les types de tests, leur couverture et leur rédaction, ici l’auteur adopte une autre approche. Par exemple, il décrit des erreurs typiques comme le test des valeurs limites. Il parle des outils de mesure de couverture de tests (qui existaient déjà à l’époque), mentionne brièvement les outils de test, le TDD, et quelques standards acceptés.
Les choses deviennent plus intéressantes à partir du chapitre sur le refactoring. Un autre exemple de boucle for testée dans différents langages montre à quel point les performances peuvent varier selon le langage utilisé. Le type de compilateur a aussi un impact important. Une table intéressante illustre la performance relative du code écrit en différents langages. Aux exemples de comparaison entre C, C++, C#, Java et Visual Basic s’ajoutent PHP et Python. Les comparaisons fréquentes concernent les performances des opérations courantes en C++ et Java. Il est difficile de dire si ces tests sont encore pertinents aujourd’hui, étant donné que les compilateurs ont évolué, de nouvelles constructions sont apparues dans les langages, et même les interprètes comme celui de PHP sont réécrits et optimisés à chaque version. Mais le message principal de ce chapitre n’est pas de comparer le temps nécessaire à tel ou tel algorithme de base (comme le calcul d'une racine carrée), mais de montrer que le même code (la même fonction) peut fonctionner de manière très différente selon le langage (parfois plus lent, parfois plus rapide).
Enfin, la section propose un exemple montrant comment le changement de types de données vers des types plus appropriés peut améliorer la vitesse d’exécution d’un algorithme (encore une fois, avec des exemples dans différents langages).
Questions systémiques
La section se compose des chapitres suivants :
- Comment la taille du programme influence la construction
- Gestion de la construction
- Intégration
- Outils de programmation
Qu'est-ce qui est intéressant ici ? Par exemple, le sujet de l'influence de la taille de l'équipe sur l'efficacité est abordé, ainsi que la part approximative des programmeurs dans le code écrit par rapport au code total en fonction de l'équipe. Il est question de la relation entre la taille du projet en lignes de code et la densité des erreurs. Les graphiques et tableaux sont peut-être quelque peu discutables, mais cela vaut la peine d'être lu. Je recommanderais même en premier lieu cette section aux managers.
Dans l'ensemble, la section est théorique, avec peu de code. Le sujet des changements de spécifications au cours du projet et de l'impact que cela peut avoir sur le calendrier est également mentionné. Les principaux facteurs liés aux programmeurs et à l'équipe, qui peuvent également influencer la vitesse, sont énumérés. L'auteur inclut parmi ces facteurs :
- l'expérience et les compétences du programmeur ;
- la motivation de l'équipe ;
- la qualité de la gestion ;
- le volume de code réutilisé ;
- le turnover ;
- la variabilité des exigences ;
- et d'autres encore.
Le sujet des relations et de la communication avec les programmeurs est abordé. Par exemple, comment les programmeurs passent leur temps. Autrement dit, le sujet du burn-out était déjà pertinent à l'époque. Un autre thème est également mentionné ici, touchant aux questions "religieuses" — comme le choix de l'IDE, la nomination et le style de code, l'utilisation des linters, etc.
Le sujet de l'intégration est discuté — étape par étape et incrémentielle, en T et d'autres encore. Les avantages et les inconvénients de chaque approche sont décrits. Mais le matériel est assez discutable, car il n'est pas fait mention des pratiques modernes de CI/CD.
Maîtrise de la programmation
En résumé, il s'agit d'une section générale du livre, qui regroupe de nombreuses autres sections et renvoie également aux chapitres déjà lus. Des conseils généraux sont précisés, avec de nombreux exemples de code — de la disposition des commentaires à la manipulation des classes et des méthodes. Je ne dirais pas que cette section peut être perçue comme la conclusion de tout le livre — plutôt comme un complément aux sections précédentes. La section se termine par des conseils moraux de l'auteur, par exemple sur l'attitude à adopter envers la paresse, la rigueur et d'autres qualités. Enfin, une vaste bibliographie est donnée, ce qui témoigne au minimum d'une approche professionnelle et d'un travail minutieux lors de la rédaction du livre.
Conclusions
Ce livre compte près de 900 pages, mais ne laissez pas cela vous effrayer, car le contenu qu'il propose est, à mon avis, bien meilleur que celui de Robert Martin. Voici les principaux avantages et inconvénients du livre.
Inconvénients :
- Le livre est énorme, et tout le monde n’a pas la capacité de lire un tel ouvrage.
- La date de publication n'est pas récente, donc certains exemples et sujets peuvent être dépassés. Par exemple, il n'est pas fait mention de certains langages modernes de programmation, et les approches actuelles du déploiement des applications et des technologies de développement logiciel ont considérablement évolué.
Avantages :
- Structure excellente et claire.
- Lecture facile.
- Chaque chapitre se termine par un résumé avec les points essentiels.
- De nombreux exemples de mauvais code sont donnés, suivis de leur amélioration en bon code.
- Le code est présenté dans différents langages, avec des comparaisons d'algorithmes entre eux.
Ce livre est indéniablement bon. Je dirais que c'est l'un des meilleurs ouvrages théoriques sur la programmation, à lire aussi bien par les débutants que par les développeurs expérimentés.