LE PROGRAMMEUR PRAGMATIQUE

Le programmeur pragmatique est un guide habile et pratique qui donne un aperçu et les bases pour être un bon programmeur, en augmentant votre spécialisation et les technicités dans le développement moderne de logiciels. Le livre a été publié en octobre 1999. Andrew Hunt y aborde les thèmes de la responsabilité personnelle et du développement de carrière, ainsi que les techniques architecturales permettant de conserver un code flexible, facile à adapter et à réutiliser. Ce livre vous apprendra à lutter contre la pourriture des logiciels, à éviter le piège de la duplication des connaissances et à rendre vos développements plus précis grâce à l’automatisation.

COMMENT CE LIVRE NOUS A-T-IL AIDÉS ?

Ce livre nous a aidés à comprendre comment les développeurs peuvent devenir de meilleurs programmeurs en comprenant les principes fondamentaux nécessaires à la réussite du développement de logiciels. Il montre qu’être un bon programmeur ne se résume pas à des compétences techniques. Il se concentre sur des sujets pratiques tels que le découplage, l’édition de puissance, le débogage et les tests, qui nous aident à aider les développeurs à construire un meilleur code pour nos clients et à devenir des consultants et des membres de grandes équipes de projet. Le livre nous a aidés à comprendre comment utiliser notre expérience pour prendre des décisions plus éclairées dans notre vie professionnelle et personnelle.

LE LIVRE EXPLIQUÉ EN MOINS DE 60 SECONDES

Le livre utilise des analogies et des histoires courtes pour présenter les méthodologies de développement et les mises en garde, par exemple la théorie des fenêtres brisées, l’histoire de la soupe de pierre ou la grenouille bouillante. Il contient également de petits exercices pour mettre en pratique vos compétences en programmation.

Le programmeur pragmatique explique que les défauts des logiciels se manifestent de différentes manières, depuis les exigences mal comprises jusqu’aux erreurs de codage. Malheureusement, les systèmes informatiques modernes sont encore limités à faire ce que vous leur dites et non ce que vous voulez qu’ils fassent.

Selon le livre, personne n’écrit un logiciel parfait. Il est donc évident que le débogage occupera une grande partie de votre journée. Le débogage est un sujet sensible et émotionnel pour de nombreux développeurs.

TROIS CITATIONS PRINCIPALES

« Les outils amplifient votre talent. Plus vos outils sont performants et mieux vous savez les utiliser, plus vous pouvez être productif ».

« La plus grande de toutes les faiblesses est la peur de paraître faible.

« L’éditeur sera le prolongement de votre main ; les touches chanteront en découpant le texte et la pensée.

RÉSUMÉ DU LIVRE ET NOTES

Chapitre 1 : Une philosophie pragmatique

  1. Le chat a mangé mon code source

Prendre des responsabilités : La responsabilité est quelque chose que vous acceptez activement ; vous vous consacrez à garantir que quelque chose est bien exécuté. Cependant, vous n’avez pas nécessairement un contrôle direct sur tous les aspects. Vous avez le droit de ne pas prendre la responsabilité d’une situation inimaginable ou comportant des risques élevés. Lorsque vous acceptez la responsabilité d’une situation, ayez l’humilité d’être tenu pour responsable. Tout le monde commet des erreurs. Par conséquent, lorsque vous faites une erreur de jugement, admettez-la honnêtement et essayez de trouver des solutions.

  1. Entropie logicielle

Le fait qu’une fenêtre cassée non réparée reste dans la maison pendant une longue période donne aux occupants de la maison un sentiment d’abandon qui finit par provoquer davantage de dégâts et de ruines. Il en va de même pour les logiciels : un mauvais morceau de code peut entraîner d’autres dommages s’il n’est pas réparé suffisamment tôt. Par conséquent, ne vivez pas avec un code destructeur. Corrigez-le dès qu’un bogue est découvert. Prenez des mesures et faites preuve d’initiative afin d’éviter d’autres dommages et de montrer que vous maîtrisez la situation.

  1. Un logiciel de qualité

Un code suffisamment bon n’implique pas un code négligé ou mal produit. Pour réussir, tous les systèmes doivent répondre aux exigences de leurs utilisateurs. Vous pouvez vous astreindre à écrire un logiciel suffisamment bon pour vos utilisateurs, les futurs responsables de la maintenance et votre tranquillité d’esprit. L’écriture d’un logiciel suffisamment bon vous rend plus productif et rend vos utilisateurs plus heureux. L’élaboration d’un code satisfaisant suppose simplement que les utilisateurs soient autorisés à s’engager dans le processus qui consiste à décider si ce que vous avez produit est satisfaisant.

Lorsque vous construisez un code suffisamment bon, sachez quand vous arrêter. Ne ruinez pas un programme exceptionnel par un embellissement et un raffinement excessifs. Passez à autre chose et laissez votre code se débrouiller seul pendant un certain temps. Il ne sera peut-être pas parfait. Ne vous inquiétez pas : il ne pourra jamais être parfait. Un bon logiciel aujourd’hui vaut mieux qu’un logiciel idéal dans un an.

Citation préférée du chapitre : «  Un excellent logiciel aujourd’hui est souvent préférable à un logiciel parfait demain. »

Chapitre 2 : Une approche pragmatique

  1. Les méfaits de la duplication

En tant que programmeur, vous recueillez, organisez, entretenez et exploitez les connaissances. Malheureusement, l’apprentissage n’est pas constant ou fixe et évolue rapidement. Votre compréhension d’une exigence peut changer après une réunion avec le client. Cela signifie que vous passez la majeure partie de votre temps à essayer de maintenir le code quotidiennement. La plupart des gens pensent que la maintenance commence lorsqu’une application est lancée, qu’elle consiste à corriger les bogues et à améliorer les fonctionnalités. Ces personnes se trompent. La maintenance n’est pas une activité distincte, mais une partie du processus de développement, car de nouvelles exigences apparaissent au fur et à mesure que vous concevez le code.

La seule façon de développer des logiciels de manière fiable et de rendre vos développements plus faciles à comprendre et à maintenir est de suivre le principe DRY (Don’t Repeat Yourself): Chaque élément de connaissance doit avoir une représentation unique, non ambiguë et faisant autorité au sein d’un système.

La plupart des doublons que nous observons entrent dans l’une des catégories suivantes :

  • Duplication imposée. Vous estimez que vous n’avez pas le choix – l’environnement semble exiger la réplication.
  • Duplication involontaire. Vous ne vous rendez pas compte que vous dupliquez les informations.
  • Duplication impatiente. Vous devenez paresseux et vous dupliquez parce que cela semble plus facile.
  • Duplication entre développeurs. Plusieurs personnes au sein d’une équipe reproduisent une information sans s’en rendre compte.
  1. Réversibilité.

Les changements n’ont pas besoin d’être extrêmes ni même immédiats. Mais à mesure que le temps passe et que votre projet progresse, vous pouvez vous retrouver coincé dans une position intenable. L’équipe de projet s’engage sur une cible plus petite avec des décisions critiques, créant une version de la réalité avec moins d’options. Le problème est que les décisions critiques ne sont pas facilement réversibles.

Rien n’est éternel, et si vous vous appuyez fortement sur un fait, vous pouvez presque garantir qu’il changera. Prévoyez la réversibilité, car aucune décision n’est définitive. Visez la flexibilité du code, de l’architecture et de l’intégration des fournisseurs.

En respectant des recommandations telles que le principe DRY, le découplage et l’utilisation de métadonnées, vous n’aurez pas à prendre de nombreuses décisions critiques et irréversibles.

  1. Balles traçantes

Les balles traceuses vous aident à trouver rapidement votre cible dans des circonstances réelles et vous fournissent, ainsi qu’à vos utilisateurs, un retour d’information. Un code traceur peut être une fonctionnalité unique mise en œuvre de bout en bout dans toutes les couches. Un code traceur atteint rapidement la cible et fournit un retour d’information immédiat. D’un point de vue pratique, il s’agit d’une solution relativement peu coûteuse. Pour obtenir le même effet dans le code, nous cherchons quelque chose qui nous amène d’une exigence à un aspect du système final rapidement, visiblement et de manière répétée.

Avantages

  • Vous disposez d’une plate-forme d’intégration.
  • Vous avez une meilleure idée des progrès réalisés.
  • Les utilisateurs ont la possibilité de voir quelque chose qui fonctionne très tôt.
  • Participez à la construction d’une structure de travail.

Code traceur ou prototypage

Vous pourriez penser que le concept de code traceur n’est rien d’autre que du prototypage ; il y a une différence. Lors du prototypage, vous cherchez à explorer des aspects spécifiques du système final. Avec un prototype réel, vous jetterez tout ce que vous avez assemblé en essayant le concept et vous le recoderez correctement en utilisant les leçons que vous avez apprises. L’approche du code traceur aborde un problème différent. Vous devez savoir comment l’application dans son ensemble s’articule. Vous voulez montrer à vos utilisateurs comment les interactions fonctionneront dans la pratique et donner à vos développeurs un squelette architectural sur lequel accrocher le code.

Citation préférée du chapitre : « Rien n’est plus dangereux qu’une idée si c’est la seule que l’on ait. »

Chapitre trois : Les outils de base

  1. Le pouvoir du texte simple

En tant que programmeur pragmatique, votre matériau de base est la connaissance. Vous recueillez les exigences comme des connaissances et vous les exprimez ensuite dans vos conceptions, vos implémentations, vos tests et vos documents. Le meilleur format pour stocker les connaissances est le texte brut.

Qu’est-ce que le texte brut ?

Le texte brut comprend des caractères imprimables afin que les gens puissent le lire et le comprendre directement. Avec le texte brut, vous vous donnez la possibilité de manipuler les connaissances à la fois manuellement et par programme en utilisant pratiquement tous les outils à votre disposition.

  1. Jeux de coquilles

Tout menuisier a besoin d’un établi approprié, solide et fiable, où il peut poser ses pièces à une hauteur convenable pendant qu’il les travaille.

En tant que programmeur manipulant des fichiers texte, votre poste de travail est l’interpréteur de commandes. L’invite de l’interpréteur de commandes vous permet d’invoquer l’ensemble de votre répertoire d’outils. L’invite de l’interpréteur de commandes vous permet de lancer des applications, des débogueurs, des navigateurs, des éditeurs et des utilitaires. Vous pouvez rechercher des fichiers, interroger l’état du système et filtrer les résultats. En programmant l’interpréteur de commandes, vous pouvez créer des macro-commandes multiplex pour les activités que vous effectuez souvent.

Utilitaires Shell et systèmes Windows

Bien que les shells de commande fournis par les systèmes Windows s’améliorent progressivement, les utilitaires de ligne de commande Windows restent inférieurs à leurs homologues Linux/Unix. Cependant, tout n’est pas perdu.

Cygnus Solutions propose un paquetage appelé Cygwin. En plus de fournir une couche de compatibilité Linux/Unix pour Windows, Cygwin est livré avec une collection de plus de 120 utilitaires Unix, y compris les favoris tels que 1s, grep et find. Les utilitaires et les bibliothèques peuvent être téléchargés et utilisés gratuitement, mais lisez leur licence. La distribution Cygwin est livrée avec l’interpréteur de commandes Bash.

  1. L’édition de puissance

Les outils sont le prolongement de votre main. Cela s’applique aux éditeurs plus qu’à tout autre outil logiciel. Choisissez un éditeur qui vous permettra de manipuler du texte aussi facilement que possible, car le texte est la matière première de la programmation.

Un éditeur

Il est préférable de connaître parfaitement un seul éditeur et de l’utiliser pour toutes les tâches d’édition : code, documentation, mémos, administration du système, etc. Avec plusieurs éditeurs, vous risquez d’être confronté au chaos et à la confusion des temps modernes. Vous devrez peut-être utiliser l’éditeur intégré dans l’IDE de chaque langue pour le codage, un produit bureautique tout-en-un pour la documentation et peut-être un autre éditeur intégré pour l’envoi de courriels. Même les touches que vous utilisez pour éditer les lignes de commande dans l’interpréteur de commandes peuvent être différentes. Il est difficile d’être compétent dans l’un ou l’autre de ces environnements si vous disposez d’un ensemble différent de conventions et de commandes d’édition dans chacun d’eux.

Choisissez donc un seul éditeur, apprenez à le connaître en profondeur et utilisez-le pour toutes les tâches d’édition. Utilisez un seul éditeur ou un seul ensemble de raccourcis clavier pour toutes les activités d’édition de texte. Vous n’aurez plus besoin de vous arrêter et de réfléchir pour manipuler du texte : les frappes nécessaires seront un réflexe. L’éditeur sera le prolongement de votre main, les touches chanteront en se frayant un chemin à travers le texte et la pensée. Assurez-vous que l’éditeur que vous choisissez est disponible sur toutes les plates-formes que vous utilisez. Emacs, vi, CRiSP, Brief et d’autres sont disponibles sur plusieurs plates-formes, souvent dans des versions avec ou sans interface graphique (écran de texte).

Caractéristiques de l’éditeur :

  • Configurable
  • Extensible
  • Programmable

Citation préférée du chapitre : « Les outils amplifient votre talent. Plus vos outils sont performants et mieux vous savez les utiliser, plus vous pouvez être productif. »

Chapitre quatre : La paranoïa pragmatique

  1. Conception par contrat

Le concept de conception par contrat est une technique simple mais puissante qui se concentre sur la documentation et l’acceptation des droits et des responsabilités des modules logiciels afin de garantir l’exactitude du programme. Un programme correct ne fait ni plus ni moins que ce qu’il prétend faire. La documentation et la vérification de cette affirmation sont au cœur de la conception par contrat. Chaque fonction et méthode d’un système logiciel fait quelque chose. Avant de commencer, la routine peut avoir des attentes quant à l’état du monde. Les attentes et les revendications comprennent

  • Conditions préalables : Qu’est-ce qui doit être valide pour que la routine soit appelée ?
  • Invariants de classe : Une classe garantit que cette condition est toujours effective du point de vue de l’appelant.
  • Postconditions : Le fait que la routine ait une postcondition implique qu’elle conclura : les boucles infinies ne sont pas autorisées.

Mise en œuvre de la conception par contrat

Le principal avantage de l’utilisation de DBC est qu’elle met au premier plan la question des exigences et des garanties. Le simple fait d’énumérer, au moment de la conception, l’étendue du domaine d’entrée, les conditions limites et ce que la routine promet de fournir ou ne promet pas de fournir constitue un pas de géant dans l’écriture d’un meilleur logiciel. Si vous n’indiquez pas ces éléments, vous programmez par coïncidence et c’est là que de nombreux projets commencent, se terminent et échouent. Dans les langages qui ne prennent pas en charge DBC dans le code, vous ne pouvez pas aller plus loin, ce qui n’est pas si mal. Après tout, DBC est une technique de conception.

  1. Les programmes morts ne mentent pas

Il est facile de tomber dans la mentalité du « ça ne peut pas arriver ». La plupart d’entre vous ont déjà écrit du code qui ne vérifiait pas qu’un fichier se fermait correctement ou qu’une instruction de trace était écrite comme prévu. Toutes choses étant égales par ailleurs, il est probable que vous n’ayez pas eu besoin de le faire, le code en question n’aurait pas échoué dans des conditions normales. Mais vous codez de manière défensive. Vous recherchez des pointeurs erronés dans d’autres parties de votre programme et vous mettez la pile à la poubelle. Vous vérifiez que les versions chargées des bibliothèques partagées sont correctes.

Toutes les erreurs vous donnent des informations. Vous pourriez vous convaincre que l’erreur ne peut pas se produire et choisir de l’ignorer. Au lieu de cela, un programmeur pragmatique se dit que quelque chose de très, très mauvais s’est produit s’il y a une erreur.

Crash, Don’t Trash (ne pas jeter à la poubelle)

L’un des avantages de détecter les problèmes le plus tôt possible est que vous pouvez vous écraser plus tôt.

Et bien souvent, le plantage de votre programme est la meilleure chose que vous puissiez faire. L’alternative peut être de continuer à écrire des données corrompues dans une base de données robuste ou de commander à la machine à laver son vingtième cycle d’essorage consécutif.

  1. Programmation assertive

Le compte ne peut pas être négatif, l’impression ne peut pas échouer, la journalisation ne peut pas échouer ou cela ne peut jamais se produire. Ne pratiquez pas ce genre de tromperie, en particulier lors du codage. Si cela ne peut pas arriver, appliquez des assertions pour vous assurer que cela n’arrivera pas.

Chaque fois que vous pensez que « cela ne pourrait jamais arriver », ajoutez du code pour le vérifier. La manière la plus simple de le faire est d’utiliser des assertions. Dans la plupart des implémentations C et C++, vous trouverez une forme d’assert ou de macro assert qui vérifie une condition booléenne. Ces macros peuvent s’avérer précieuses. Les assertions permettent également de vérifier le fonctionnement d’un algorithme. Supposons que vous ayez écrit un algorithme intelligent ; les assertions vérifieront qu’il fonctionne.

N’appliquez pas d’assertions à la place d’une véritable gestion des erreurs. Les assertions vérifient des choses qui ne devraient jamais se produire et assurez-vous que la méthode d’assertion que vous utilisez n’a pas d’effets secondaires susceptibles de créer de nouvelles erreurs.

Laissez les affirmations en place

Les personnes qui écrivent des compilateurs et des environnements linguistiques ont une interprétation erronée des assertions qui est largement répandue. Cette interprétation est la suivante : « Les assertions ajoutent une certaine surcharge au code. Parce qu’elles vérifient des choses qui ne devraient jamais se produire, elles ne seront déclenchées que par un bogue dans le code. Une fois que le code a été testé et livré, désactivez les assertions pour accélérer l’exécution du code. »

Citation préférée du chapitre : « Les assertions ajoutent une certaine surcharge au code. Parce qu’elles vérifient des choses qui ne devraient jamais se produire, elles ne seront déclenchées que par un bogue dans le code. Une fois que le code a été testé et livré, elles ne sont plus nécessaires et doivent être désactivées pour accélérer l’exécution du code. »

Chapitre 5 : Se plier ou se rompre

  1. Le découplage et la loi de Déméter

Organisez votre code en modules et contrôlez l’interaction entre eux. Si un module est compromis et doit être remplacé, les autres modules doivent continuer à fonctionner.

Minimiser l’accouplement

Il n’y a rien de mal à ce que les modules se connaissent les uns les autres. Cependant, vous devez faire attention au nombre d’autres modules avec lesquels vous interagissez et, plus important encore, à la manière dont vous interagissez avec eux. Lorsque vous demandez un service spécifique à un objet, vous souhaitez que ce service soit exécuté en votre nom. Vous ne voulez pas que l’objet vous donne une entité tierce avec laquelle vous devez traiter pour obtenir le service requis.

La loi de Déméter

La loi de Déméter pour les fonctions stipule que toute méthode d’un objet ne doit appeler que des processus appartenant à lui-même, tout paramètre passé dans la méthode, tout objet qu’il a créé et tout objet composé détenu directement. La loi de Déméter vise à minimiser le couplage entre les modules d’un programme donné ; elle vous empêche de pénétrer dans un objet pour accéder aux méthodes d’un troisième objet. L’écriture d’un code « timide » honore la loi de Demeter et permet d’atteindre l’objectif de minimisation du couplage entre les modules.

  1. Métaprogrammation

Les détails nuisent considérablement à votre code parfait s’ils changent fréquemment. Chaque fois que vous devez modifier le code pour l’adapter à une modification de la logique commerciale, de la législation ou des goûts du jour de la direction, vous courez le risque de casser le système en introduisant un nouveau bogue.

Assez de détails ! Sortez-les du code. Pendant que vous y êtes, vous pouvez rendre votre code hautement configurable et « souple ». C’est-à-dire facilement adaptable aux changements.

Configuration dynamique

Configurez, n’intégrez pas. Vous devez faire en sorte que vos systèmes soient hautement configurables. Il ne s’agit pas seulement de couleurs d’écran ou de texte d’invite, mais d’éléments profondément ancrés tels que le choix des algorithmes, des produits de base de données, de la technologie des logiciels intermédiaires et du style de l’interface utilisateur, qui doivent être appliqués en tant qu’options de configuration et non par le biais de l’intégration ou de l’ingénierie.

Quand configurer

Représentez vos métadonnées de configuration en texte clair ; cela vous facilitera la vie. Mais quand un programme doit-il lire cette configuration ? De nombreux programmes n’analysent ce type de données qu’au démarrage, ce qui est regrettable car vous serez obligé de redémarrer l’application lorsque vous aurez besoin d’en modifier la présentation. Une approche plus souple consiste à écrire des programmes qui rechargent leur configuration en cours d’exécution. Bien que cette flexibilité ait un coût, elle est plus complexe à mettre en œuvre.

Pensez donc à la manière dont les utilisateurs se serviront de votre application : s’il s’agit d’un processus serveur de longue durée, vous devrez prévoir un moyen de relire et d’appliquer les métadonnées pendant que le programme est en cours d’exécution. Pour une petite application client à interface graphique qui redémarre rapidement, vous n’en aurez peut-être pas besoin.

  1. Couplage temporel

Ici, l’auteur parle du temps comme d’un élément de conception du logiciel lui-même. Deux aspects du temps sont importants pour vous : la coexistence (les choses qui se produisent simultanément) et l’ordonnancement (les positions relatives des choses dans le temps). Dans le cadre du couplage temporel, la coexistence est toujours appelée avant l’ordre ; vous ne pouvez exécuter qu’un seul rapport à la fois ; après, attendez que l’écran se redessine avant de cliquer sur un bouton.

Citation préférée du chapitre : « Aucun génie ne peut venir à bout d’un souci du détail ».

Chapitre six : Pendant que vous codez

  1. Programmation par coïncidence

Des centaines de pièges vous guettent chaque jour en tant que développeur. N’oubliez pas de ne pas tirer de fausses conclusions. Évitez de programmer par coïncidence, en vous fiant à la chance et aux succès accidentels, au profit d’une programmation délibérée. Lorsque vous programmez par coïncidence et que votre code échoue, vous ne saurez pas pourquoi il a échoué parce que vous ne saviez pas pourquoi il fonctionnait en premier lieu, compte tenu des tests limités que vous avez effectués.

Accidents de mise en œuvre

Les accidents de mise en œuvre sont des choses qui se produisent simplement parce que c’est ainsi que le code est écrit. Vous finissez par vous appuyer sur des erreurs ou des conditions limites non documentées. La condition limite sur laquelle vous vous appuyez peut n’être qu’un accident. Dans d’autres circonstances (une résolution d’écran différente, par exemple), elle pourrait se comporter différemment.

Les comportements non documentés peuvent changer avec la prochaine version de la bibliothèque.

Comment programmer délibérément

  • Ne codez pas les yeux bandés.
  • Ne vous fiez qu’à des éléments fiables. Ne vous fiez pas aux accidents ou aux hypothèses.
  • Documentez vos hypothèses.
  1. Vitesse de l’algorithme

En tant que programmeur pragmatique, vous évaluez les ressources des algorithmes, telles que le temps, le processeur et la mémoire. La plupart des algorithmes non triviaux gèrent une certaine forme d’entrée variable ; la taille de cette entrée aura un impact sur l’algorithme. Plus l’information est importante, plus le temps d’exécution est long ou plus la mémoire est utilisée.

Vous constaterez que vous vérifiez inconsciemment les exigences en matière de temps d’exécution et de mémoire chaque fois que vous écrivez quelque chose qui contient des boucles ou des appels récursifs. Ce processus confirme rapidement que vos actions sont raisonnables compte tenu des circonstances. Par conséquent, vous vous retrouvez à effectuer une analyse plus détaillée. C’est alors que la notation O() devient utile. La notation O() est un moyen mathématique de traiter les approximations.

  1. Refonte

Le code doit évoluer, il n’est pas statique. Au fur et à mesure qu’un programme se développe, il devient nécessaire de repenser les décisions antérieures et de retravailler certaines parties du code. La réécriture, la restructuration et la réarchitecture d’un corps de code existant, en modifiant sa structure interne sans changer son comportement externe, sont connues sous le nom de « refactoring ».

Quand faut-il remanier ?

Si vous tombez sur une pierre d’achoppement parce que le code n’est plus tout à fait adapté ou que vous remarquez deux choses que vous devriez fusionner, n’hésitez pas à le modifier. Voici quelques éléments qui peuvent faire qu’un code mérite d’être remanié :

Duplication. Vous avez découvert une violation du principe DRY (Don’t Repeat Yourself).

Conception non orthogonale. Vous avez découvert un code ou une procédure qui pourrait être rendu plus orthogonal (orthogonalité).

Des connaissances dépassées. Les choses changent, les exigences dérivent et votre compréhension du problème augmente. Le code doit suivre.

Performance. Vous devez déplacer des fonctionnalités d’une zone du système à une autre pour améliorer les performances.

  1. Code facile à tester

Dans les puces et les systèmes plus complexes, les développeurs de matériel incluent des fonctions telles qu’un autotest intégré (BIST) complet qui exécute des diagnostics de base en interne et un mécanisme d’accès aux tests (TAM) qui fournit un harnais de test permettant à l’environnement externe de fournir des stimuli et de recueillir les réponses de la puce. Vous pouvez faire la même chose dans les logiciels, intégrer la testabilité dans le logiciel dès le début et tester chaque élément en détail avant d’essayer de les relier entre eux.

Tests unitaires

Les tests au niveau de la puce pour le matériel sont équivalents aux tests unitaires pour les logiciels. Les tests sont effectués sur chaque module de manière isolée afin de vérifier son comportement. Vous pouvez mieux comprendre comment un module réagira dans le vaste monde une fois que vous l’avez testé de manière approfondie dans des conditions contrôlées.

Un test unitaire de logiciel est un code qui exerce un module. En général, le test unitaire met en place un environnement artificiel et évoque ensuite des routines dans le module testé. Le test unitaire vérifie ensuite les résultats obtenus, soit par rapport à des valeurs connues, soit par rapport aux résultats des exécutions précédentes du même test.

Plus tard, lorsque vous assemblerez vos « circuits intégrés logiciels » en un système complet, vous aurez la certitude que les différentes parties fonctionnent comme prévu. Vous pourrez alors utiliser les mêmes moyens de test unitaire pour tester le système dans son ensemble.

Citation préférée du chapitre : « Tous les logiciels que vous écrivez seront testés – si ce n’est pas par vous et votre équipe, ce sera par les utilisateurs finaux – alors autant prévoir des tests approfondis. »

Chapitre sept : Avant le projet

  1. Le puits d’exigence

Le recueil des besoins est une étape précoce du projet. La collecte implique que les exigences sont déjà là, il suffit de les trouver. Mettez-les dans votre panier et continuez votre chemin. Bien que cela ne fonctionne pas comme ça, les exigences font rarement surface. Elles sont enfouies sous des couches de suppositions, d’idées fausses et de politiques.

Recherche d’exigences

Comment identifier un besoin réel lorsque vous creusez dans la poussière environnante ? La réponse est à la fois complexe et simple. La réponse directe est l’énoncé de quelque chose qui doit être accompli. D’un autre côté, très peu d’exigences sont claires, ce qui rend l’analyse des exigences complexe.

Si l’exigence est formulée comme suit : « Seul le personnel peut consulter un dossier d’employé », vous devrez coder un test simple chaque fois que l’application accède à ces fichiers. En revanche, si l’exigence est « Seuls les utilisateurs autorisés peuvent accéder à un dossier d’employé », le développeur concevra et mettra probablement en œuvre une sorte de système de contrôle d’accès. En cas de changement de politique, seules les métadonnées de ce système devront être mises à jour. En rassemblant les exigences de cette manière, vous obtiendrez un système bien conçu pour prendre en charge les métadonnées.

  1. Résoudre des énigmes impossibles

Pensez aux puzzles du monde réel que l’on trouve dans les cadeaux de Noël ou dans les vide-greniers. Vous devez retirer l’anneau ou faire entrer les pièces en forme de T dans la boîte. Vous retirez l’anneau et découvrez rapidement que les solutions apparentes ne permettent pas de résoudre le puzzle. La réponse se trouve ailleurs. Le secret pour résoudre l’énigme est d’identifier les véritables contraintes et d’y trouver une solution. Certaines contraintes sont absolues, d’autres ne sont que des idées reçues. Les contraintes fondamentales doivent être respectées, même si elles semblent déplaisantes ou stupides. En revanche, certaines contraintes apparentes peuvent être inexactes.

Ne pensez pas en dehors de la boîte – trouvez la boîte

Lorsque vous êtes confronté à un problème insoluble, énumérez toutes les possibilités qui s’offrent à vous.

Ne rejetez rien, même si cela vous semble inutilisable ou stupide. Parcourez la liste et expliquez pourquoi vous ne pouvez pas emprunter telle ou telle voie. Pouvez-vous le prouver ?

  1. Pas avant que vous ne soyez prêt

Lorsque vous ressentez un doute ou une réticence persistante face à une tâche, prêtez-y attention. Il se peut que vous ne parveniez pas à déterminer exactement ce qui ne va pas. Donnez-lui du temps et vos doutes se cristalliseront probablement en quelque chose de plus solide, quelque chose que vous pourrez résoudre. Le développement de logiciels n’est pas encore une science. Laissez votre instinct contribuer à vos performances.

Bon jugement ou procrastination ?

Le lancement d’un nouveau projet ou même d’un nouveau module dans le cadre d’un projet existant peut être une expérience douloureuse. Nombreux sont ceux qui préfèrent remettre à plus tard l’engagement initial de commencer. Alors, comment savoir si vous êtes en train de procrastiner plutôt que d’attendre de manière responsable que tous les éléments se mettent en place ?

Dans ces circonstances, une technique qui vous conviendra est le prototypage. Choisissez un domaine qui vous semble difficile et commencez à produire des preuves de concept. Peu après, vous penserez que vous perdez votre temps. Cet ennui est probablement une bonne indication que votre réticence initiale n’était qu’un désir de repousser l’engagement de commencer. Abandonnez le prototype et lancez-vous dans le développement proprement dit.

Citation préférée du chapitre : « La perfection est atteinte, non pas quand il n’y a plus rien à ajouter, mais quand il n’y a plus rien à enlever…. »

Chapitre huit: Des projets pragmatiques

  1. Des tests impitoyables

Testez tôt, testez souvent et testez automatiquement. Vous devriez commencer à tester dès que vous avez le code. Développez des plans de test élaborés pour vos projets. Les équipes qui utilisent des tests automatisés ont de bien meilleures chances de réussite. Les tests qui s’exécutent à chaque version sont beaucoup plus efficaces que des plans de test sur une étagère. N’oubliez pas que plus vous trouvez un bogue tôt, moins il est coûteux d’y remédier. « Codez un peu, testez un peu.

Pour que votre projet soit satisfaisant, il doit comporter plus de code de test que de code de production. Le temps perdu à produire ce code de test en vaut la peine et coûte moins cher à long terme. Vous avez également une chance de créer un produit dont le nombre de défauts est proche de zéro.

  1. De grandes attentes

La réussite du projet de votre équipe se mesure à la manière dont il répond aux attentes de ses utilisateurs. Si votre projet ne répond pas à leurs attentes, il est considéré comme un échec, quelle que soit la qualité du produit livrable en termes absolus.

L’effort supplémentaire

Dépassez gentiment les attentes de vos utilisateurs. N’effrayez pas vos utilisateurs, mais surprenez-les. Donnez-leur un peu plus que ce qu’ils attendaient. L’effort supplémentaire requis pour ajouter au système une fonction orientée vers l’utilisateur se paiera de lui-même, à maintes reprises, en termes de bonne volonté.

  1. Fierté et préjugés

En tant que programmeur pragmatique, vous ne devez pas fuir les responsabilités. Au contraire, vous devez vous réjouir des défis qui se présentent à vous et faire connaître votre expertise professionnelle. Si vous êtes responsable d’une conception ou d’un morceau de code, vous ferez un travail dont vous serez fier.

Signez votre travail

Soyez fier de votre travail. « Vous avez écrit ceci et vous devriez être fier de votre travail. Votre signature devrait être reconnue comme un indicateur de qualité. Les gens devraient voir votre nom sur un morceau de code et s’attendre à ce qu’il soit solide, bien écrit, testé et documenté – un travail professionnel réalisé par un vrai professionnel.

Citation préférée du chapitre : « La civilisation progresse en augmentant le nombre d’opérations importantes que nous pouvons effectuer sans réfléchir. »

COMMENT CE LIVRE PEUT-IL AIDER LES DÉVELOPPEURS DE LOGICIELS ?

« The Pragmatic Programmer » d’Andrew Hunt et David Thomas est un ouvrage classique sur le développement de logiciels qui offre des conseils pratiques et des techniques pour améliorer la façon dont les développeurs travaillent. Il aborde des sujets tels que le débogage, les tests, l’automatisation et la gestion de projet, ainsi que l’importance de la communication et de l’apprentissage continu. En suivant les conseils de l’ouvrage, les développeurs peuvent améliorer leurs compétences en matière de codage, accroître leur productivité, travailler plus efficacement, devenir des membres d’équipe plus performants et livrer de meilleurs produits logiciels.

DevologyX OÜ
Harju maakond, Tallinn, Lasnamäe
linnaosa,
Vaike-Paala tn 1, 11415

+372 6359999
[email protected]
DevologyX Limited
Nakawa Business Park
Kampala
Uganda

+256206300922
[email protected]

DevologyX Pty Ltd
Tijger Park 3
Willie van Schoor Drive
Bellville
Cape Town
7530

[email protected]

DevologyX OÜ
Harju maakond, Tallinn, Lasnamäe
linnaosa,
Vaike-Paala tn 1, 11415

+372 6359999
[email protected]
DevologyX Limited
Nakawa Business Park
Kampala
Uganda

+256206300922
[email protected]

DevologyX Pty Ltd
TijgerPark 3
Willie van Schoor Drive
Bellville
Cape Town
7530

[email protected]