5 Citations de programmation Célèbres, Expliquées
Être programmeur, c’est s’inscrire à une vie d’apprentissage constant. La fontaine de nouveautés — nouvelles fonctionnalités, nouveaux langages, nouveaux outils, nouveaux frameworks — ne cesse de jaillir. Mais l’informatique est aussi un domaine étonnamment traditionnel qui repose sur des principes éprouvés par le temps. Nous avons ajouté une programmation orientée objet, du matériel moderne et de l’intelligence artificielle. Mais malgré ces changements, bon nombre des idées qui ont été formulées pour la première fois il y a une génération sont toujours vraies aujourd’hui.
Dans cet article, j’ai disséqué quelques-unes de mes citations préférées sur l’informatique. La seule condition que j’ai fixée est que chaque devis doit avoir au moins vingt ans. Car alors que la vieille technologie devient rapidement inutile, les anciens commandements de nos ancêtres programmeurs ont beaucoup plus de résistance.
” Tous les problèmes en informatique peuvent être résolus par un autre niveau d’indirection.” – David Wheeler
Voici une citation compsci souvent répétée que peu de développeurs veulent expliquer. Mais c’est l’une de mes vérités de programmation préférées, car elle frappe au cœur de ce qu’est le codage.
La façon la plus simple de commencer à penser à l’indirection est d’imaginer des couches. Par exemple, supposons que vous ayez un petit projet qui doit intégrer le composant A au composant B:
Les deux composants sont standardisés, vous ne pouvez donc pas les ouvrir et changer leur façon de travailler. Vous pouvez créer un tout nouveau composant (PlugTwoProngVariant
) mais c’est beaucoup de travail et une duplication inutile. Une meilleure approche consiste à ajouter une couche entre les deux pièces — un adaptateur qui s’adapte aux deux composants et se traduit entre eux.
Maintenant, si l’indirection consistait simplement à ajouter un nouveau calque pour assembler des pièces incompatibles, ce serait bien mais étroitement utile. Mais l’idée de résoudre des problèmes en construisant autour d’eux est un concept qui s’étend du bas au haut de l’informatique. Vous le voyez lorsque vous essayez d’adapter un nouveau modèle de données à une ancienne interface utilisateur. Vous le voyez lorsque vous essayez d’adapter une application héritée à un nouveau backend de service Web. Vous le voyez lorsque vous devez utiliser des fonctionnalités de niveau supérieur telles que la journalisation et la mise en cache, ou coordonner des services de niveau supérieur tels que la messagerie et les transactions. Et au sommet de la pyramide, vous aborderez des sujets raréfiés comme l’apprentissage automatique (lorsque vous ne pouvez pas coder le comportement dont vous avez besoin, écrivez une autre couche de code qui le comprendra pour vous).
Beaucoup de gens vous diront que le codage consiste à écrire des instructions explicites dans un langage que même les ordinateurs idiots peuvent comprendre. Mais la citation de David Wheeler révèle un meilleur aperçu. Une bonne programmation consiste à gravir les échelons de l’abstraction pour arriver aux solutions les plus générales.
Citation liée au bonus:
L’indirection est puissante, mais la complexité a un coût. Les gens citent très rarement la remarque immédiate de Wheeler sur l’indirection:
” Mais cela créera généralement un autre problème.”- David Wheeler
Cette vérité a gardé les programmeurs en activité depuis.
Sur la simplicité
” La simplicité est la condition préalable à la fiabilité.” – Edsger Dijkstra
Les programmeurs avisés ne manquent pas de nous avertir de ne pas trop compliquer notre code. Mais peu de gens mettent le coût de la complexité plus clairement que le pionnier néerlandais de l’informatique Edsger Dijkstra.
Voici l’aperçu: vous ne choisissez pas la simplicité comme un cadeau pour l’avenir. Vous ne le faites pas parce que vous anticipez la possibilité de réutiliser votre code, ou parce que vous voulez qu’il soit plus propre lors d’une révision de code, ou parce que vous voulez le rendre plus facile à modifier. (Bien que tous ces avantages soient précieux!) Vous le faites parce que la simplicité est une condition préalable. Sans simplicité, vous ne pouvez jamais disposer d’un code fiable auquel vous pouvez faire confiance pour gérer une entreprise ou gérer vos données.
Pour accepter le point de Dijkstra, nous devons redéfinir ce que signifie “bon code”. Ce n’est pas le code le plus court. Ce n’est pas nécessairement le code le plus rapide. Ce n’est certainement pas le code le plus intelligent. C’est un code auquel on peut faire confiance.
Citation liée au bonus:
L’une des meilleures façons de garder le code simple est de se rappeler que moins c’est plus. Dijkstra propose une métrique pour nous aider à garder cela à l’esprit:
” Si nous voulons compter des lignes de code, nous ne devons pas les considérer comme des “lignes produites” mais comme des “lignes dépensées”.'” – Edsger Dijkstra
Sur la lisibilité et les réécritures
” Il est plus difficile de lire du code que de l’écrire.” – Joel Spolsky
À première vue, cette citation de Joel Spolsky, co-créateur de Software legend et de StackOverflow, semble vraie mais faussement superficielle. Oui, le code peut être dense, laconique et fastidieux. Et ce n’est pas seulement le code des autres. Si vous regardez votre propre travail d’il y a un an, vous aurez probablement besoin de temps pour trier la logique que vous connaissiez intimement.
Mais la perspicacité de Spolsky vient avec une torsion. Le danger du code que vous ne pouvez pas lire n’est pas seulement évident (il est difficile de le changer et de l’améliorer). Au lieu de cela, le plus grand danger est que le code complexe semble être pire qu’il ne l’est réellement. En fait, le fardeau d’essayer de comprendre le code déjà écrit de quelqu’un d’autre est si grand que vous pourriez être tenté de faire ce que Spolsky appelle la pire erreur possible — décider de réécrire ce code à partir de zéro.
Ce n’est pas que les réécritures ne peuvent pas améliorer l’architecture d’un système. Ils le peuvent certainement. Mais ces améliorations se font à grands frais. Ils réinitialisent l’horloge sur les tests et la correction de bogues, deux activités qui prennent beaucoup plus de temps que le simple codage. Les réécritures sont tentantes car elles jouent sur l’un des biais les plus courants dans le développement de logiciels: Nous sous-estimons l’effort de faire des choses conceptuellement simples. C’est pourquoi les 5% finaux d’un projet prennent 50% du temps. Les choses faciles peuvent prendre étonnamment du temps! Et rien ne semble plus facile que de résoudre un problème que vous avez déjà résolu.
Donc, si vous ne devez pas tout réécrire pour le rendre parfait, quelle est la meilleure solution? La réponse est d’impliquer chaque développeur dans un refactoring constant. Cela vous donne une petite amélioration continue du code — de vraies récompenses avec des risques minimes. Vous pouvez améliorer la lisibilité en cours de route.
Citation liée au bonus:
Si vous avez encore des doutes sur l’importance de la lisibilité, Martin Fowler aide à le mettre en perspective:
” Tout imbécile peut écrire du code qu’un ordinateur peut comprendre. Les bons programmeurs écrivent du code que les humains peuvent comprendre.”- Martin Fowler
En d’autres termes, le travail d’un programmeur n’est pas seulement de faire fonctionner les choses, mais de donner un sens aux choses.
En répétition
” Ne te répète pas. Chaque connaissance doit avoir une représentation unique, sans ambiguïté et faisant autorité au sein d’un système.”- Andy Hunt et Dave Thomas
Tout programmeur qui se respecte sait que la répétition est le cœur de beaucoup de mal. Si vous écrivez la même chose à différents endroits, vous faites un travail supplémentaire d’écriture, de test et de débogage. Pire encore, vous introduisez la possibilité d’incohérences — par exemple, si une partie du code est mise à jour mais que d’autres routines similaires ne sont pas mises en accord. Un programme incohérent est un programme auquel vous ne pouvez pas faire confiance, et un programme auquel vous ne pouvez pas faire confiance n’est plus une solution viable.
Cependant, le code n’est pas le seul endroit où la répétition fait des ravages. Cette version de la fameuse règle “ne vous répétez pas” (DRY) étend le principe de non-duplication pour couvrir les autres endroits où les incohérences peuvent se cacher. Nous ne parlons plus de duplication de code. Nous parlons également de répétition dans un système – et un système a de nombreuses façons différentes d’encoder les connaissances. Ils comprennent:
- Instructions de code
- Commentaires de code
- Documentation du développeur ou du client
- Schémas de données (par exemple, tables de base de données)
- D’autres spécifications, telles que les plans de test, les documents de flux de travail et les règles de construction
Tous ces niveaux peuvent se chevaucher les uns avec les autres. Et quand ils le font, ils risquent d’introduire des versions différentes de la même réalité. Par exemple, que se passe-t-il si la documentation décrit une façon de travailler mais que l’application en suit une autre ? Qui a la propriété de la vérité ? Que se passe-t-il si les tables de base de données ne correspondent pas au modèle de données dans le code? Ou les commentaires décrivent le fonctionnement d’un algorithme qui ne correspond pas à son implémentation réelle? Chaque système a besoin d’une représentation unique et autoritaire dont tout le reste dérive.
Incidemment, les versions concurrentes de la vérité ne sont pas seulement un problème dans les projets à petite échelle ou le code mal conçu. L’un des meilleurs exemples a éclaté dans le public avec la bataille entre XHTML et HTML5. Un camp a fait valoir que la spécification était la vérité officielle et que les navigateurs devaient être corrigés pour la suivre. L’autre faction a affirmé que le comportement du navigateur était la norme de facto, car c’est ce que les concepteurs avaient à l’esprit lorsqu’ils écrivaient des pages Web. En fin de compte, la version du navigateur de la vérité a gagné. À partir de ce moment, HTML5 était ce que les navigateurs faisaient — y compris les raccourcis qu’ils autorisaient et les erreurs qu’ils acceptaient.
Devis lié au bonus:
La possibilité pour le code et les commentaires de se contredire a ouvert un débat houleux sur la question de savoir si les commentaires font plus de mal que de bien. Les partisans de la programmation extrême les traitent avec une suspicion ouverte:
” Le code ne ment jamais; les commentaires le font parfois.” – Ron Jeffries
Sur Des problèmes difficiles
” Il n’y a que deux choses difficiles en informatique: l’invalidation du cache et la dénomination des choses.” – Phil Karlton
À première vue, cette citation semble être une blague de programmation amusante mais ordinaire. Le contraste entre quelque chose qui semble difficile (invalidation du cache) et quelque chose qui semble indolore (nommer des choses) est instantanément relatable. Chaque programmeur a investi des heures de travail pour résoudre un problème ridiculement trivial, comme une paire de paramètres passés dans le mauvais ordre ou une variable à majuscule incohérente (merci JavaScript). Tant que les humains auront besoin de s’associer à des machines pour faire avancer les choses, la programmation sera un mélange de planification système de haut niveau et de fautes de frappe triviales.
Mais si vous jetez un deuxième coup d’œil à la citation de Phil Karlton, il y a plus à déballer. Nommer les choses n’est pas difficile simplement parce que la vie d’un programmeur est régulièrement gâchée par de minuscules maux de tête. C’est aussi parce que la question du nommage est en fait la limite du travail le plus important de chaque programmeur: la conception de logiciels. En d’autres termes, comment écrivez-vous du code clair, propre et cohérent?
Il existe de nombreuses façons de se tromper de dénomination. Nous avons tous vu des variables nommées d’après des types de données (myString
, obj
), abréviations (pc
pour le catalogue de produits), quelques détails d’implémentation triviaux (swappable_name
, formUserInput
), ou même rien du tout (ret_value
, tempArray
). Il est facile de tomber dans le piège de nommer une variable en fonction de ce que vous en faites à ce moment-là plutôt que de ce qu’elle contient. Et les valeurs booléennes sont particulièrement délicates — progress
est-il défini lorsque la progression commence, indique-t-il que vous devez afficher des informations de progression dans l’interface utilisateur ou signaler quelque chose de complètement différent?
Mais les noms de variables ne sont que le début. Nommer des classes soulève la question de savoir comment diviser le code en parties indépendantes. Nommer des membres publics façonne la façon dont vous présentez l’interface qui permet à une partie de votre application d’interagir avec une autre. Le verrouillage de ces noms ne décrit pas seulement ce qu’un morceau de code peut faire, il détermine ce qu’il fera.
Devis lié au bonus:
” Il y a deux choses difficiles en informatique: l’invalidation du cache, la dénomination des choses et les erreurs hors-un.” – Léon Bambrick