Comment écrire g̶o̶o̶d non, bon code

Feb 09 2023
Une opinion non scientifique et complètement subjective d'un développeur en ligne aléatoire.
qui est ce type qui pense être ? Qu'est-ce qu'il sait sur l'écriture de "grand" code ? ! Vous auriez 100% raison de penser cela - et pour être tout à fait honnête… j'ai beaucoup plus d'expérience dans l'écriture de code pas génial. pas grand code écrit pour de nombreuses raisons (certaines énumérées ci-dessous) Malgré ma profonde expérience avec le code sous-optimal - j'ai près d'une décennie d'expérience en demandant à l'ordinateur (aussi gentiment que possible) de faire les choses que moi et d'autres humains voulons.
Live Oaks (Un bel organisme dynamique complexe) - Site historique de Wormsloe, Savannah, Géorgie, États-Unis par Ryan Arnst

qui est ce type qui pense être ? Qu'est-ce qu'il sait sur l'écriture de "grand" code ? !

Vous auriez 100% raison de penser cela - et pour être tout à fait honnête… j'ai beaucoup plus d'expérience dans l'écriture de code pas génial.

pas grand code est écrit pour de nombreuses raisons (certaines énumérées ci-dessous)

  1. c'est dur
  2. "génial" est subjectif
  3. le logiciel n'est jamais fini (ne peut pas "être" génial, doit "rester" génial)
  4. la qualité peut changer en fonction des exigences actuelles
  5. beaucoup de logiciels fonctionnels ne sont pas géniaux (mauvais modèles)
  6. les personnes qui veulent des logiciels ne sont souvent pas des ingénieurs en logiciel
  7. …

Malgré ma profonde expérience avec le code sous-optimal - j'ai près d'une décennie d'expérience en demandant à l'ordinateur (aussi gentiment que possible) de faire les choses que moi et d'autres humains voulons.

Au cours de cette période, j'ai appris à apprécier divers concepts et modèles, et j'ai également appris une profonde méfiance envers les autres.

Dans cet article, je vais décrire certains des bons et des mauvais logiciels - et fournir des preuves à l'appui de personnes réellement intelligentes.

Bienvenue dans la balade

C'est quoi "génial"

Commençons par définir ce qu'est "grand". Cependant, il pourrait être plus facile de définir en indiquant rapidement ce qu'il n'est pas.

Le grand code est

  1. pas difficile à lire
  2. pas difficile de raisonner
  3. ne vous pousse pas à vous détester aujourd'hui ou 7 jours après l'avoir écrit
  1. 90% de structure et 10% de syntaxe
  2. une fonction d'abstraction d'informations associée à une gestion prévisionnelle des ressources
  3. un ami des mathématiques (en particulier la théorie des ensembles/catégories)
  4. écrit pour les humains et non pour le matériel

1. 90 % de structure et 10 % de syntaxe

Toutes ces idées sont inspirées par des sujets beaucoup plus complets et plus profonds. En ce qui concerne la structure, nous pouvons nous tourner vers le paradigme de programmation SOLID.

SOLID représente un ensemble de 5 "règles" qui doivent être suivies pour créer un logiciel maintenable. Concepts énumérés ci-dessous

S - Single-responsiblity Principle
O - Open-closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D - Dependency Inversion Principle

Ces principes tournent autour de la puissance de la programmation orientée objet (aimez-la ou détestez-la) et décrivent une manière élégante de découper vos abstractions en morceaux conviviaux.

En suivant ces principes, vous pouvez éviter de nombreuses complexités désagréables qui surviennent dans les logiciels fonctionnels.

Par exemple, avec les principes SOLID, vous réduisez l'empreinte de votre code et centrez les fichiers autour de fonctionnalités communes ; ce qui facilite la navigation et l'ajout/la suppression de fonctionnalités sans affecter les autres parties de votre base de code.

Ces problèmes sont totalement évités au niveau de la structure de votre application — plutôt qu'au niveau du code

La propreté au niveau de la structure est un moyen puissant d'imposer une organisation durable.

Article facile à digérer sur SOLID par Digital Ocean : ici

Si cela ne suffisait pas, l'oncle Bob continue de lancer des pétards .

Je recommanderais vivement son livre le plus récent sorti en 2017 (et honnêtement tout ce qui est plus récent aussi).

"Architecture propre : guide de l'artisan sur la structure et la conception des logiciels" -https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/

Ce livre explore comment vous pouvez étendre ces concepts au niveau du système .

Au fur et à mesure que nous déplaçons davantage d'applications vers « le cloud » et que nous tirons parti des services distribués. Ces principes de conception ont de plus en plus d'impact sur la grandeur de votre code.

un bon code n'est qu'un outil qui remplit la structure de la conception de vos applications, votre système doit être exprimé via sa structure et non sa syntaxe.

2. une fonction d'abstraction d'informations associée à une gestion prévisionnelle des ressources

Euh, quoi. Tu m'as vraiment perdu avec celui-là. une fonction de quoi?

décomposons-le.

"une fonction d'abstraction d'informations" est une manière concise d'exprimer que notre code est le résultat de nos abstractions .

En d'autres termes, notre code reflète la façon dont nous avons décidé de découper les concepts de notre application.

Plus concrètement ; Si nous sommes confrontés à un problème et que nous décidons de créer des « Utilisateurs » et des « Sessions », nous avons effectivement découpé notre problème en ces idées abstraites d'utilisateurs et de sessions.

… d'accord Je pense que nous avons couvert "une fonction d'abstraction d'informations".

Ensuite, nous associons cela à la « gestion des ressources prédites », qui est une façon élégante de dire que les ingénieurs en logiciel sont chargés de pouvoir voir dans l'avenir - et de construire des systèmes capables de résister aux changements futurs

Si vous ne le saviez pas, c'est de votre faute en tant que programmeur si vous n'avez pas utilisé le nouveau framework un an avant sa création. Comment ne sais-tu pas ! ? (veuillez lire comme du sarcasme - je vous promets que ce n'est pas personnel).

Donc, pour résumer; la qualité de notre code n'est pas toujours sa complexité de calcul, son nombre de lignes ou ses noms de variables élégants.

C'est la capacité de découper efficacement votre problème en morceaux abstraits qui résisteront aux changements imprévisibles de demain.

Oui oui oui, je sais; cela ne semble pas possible. Eh bien, ce n'est pas le cas - et c'est notre travail en tant que développeur de gérer les choses que nous savons et les choses que nous savons que nous ne savons pas.

C'est un exercice d'évaluation des risques et de planification des coûts - hein, je ne savais pas que vous vous étiez inscrit.

Cependant, il y a de l'espoir !

En suivant des concepts fiables (d'autres à venir sous peu), nous pouvons nous renforcer et renforcer nos applications pour un monde en évolution.

Avant d'entrer dans les très bonnes choses, nous pouvons reconnaître ici quelques idées dignes de « confiance ».

  • Organismes de normalisation (il y a des gens qui y ont déjà beaucoup réfléchi - et ils apprécieraient vraiment si vous utilisiez leur excellent travail. Cela s'applique particulièrement aux algorithmes, à la sécurité, à la multiplateforme et à d'autres choses vraiment importantes comme les codes QR).
  • Langages statiques et fortement typés (honnêtement, il ne s'agit pas vraiment des problèmes de sécurité de bas niveau que vous éviterez. Il s'agit de la nature centrée sur l'homme des types. Premièrement, si vous violez le type dans votre code, le compilateur vous criera dessus, et deux, les autres développeurs sauront réellement ce que fait votre code).
  • Poésie (moins sur les mots et plus sur la capacité à communiquer une signification complexe avec peu de symboles. Votre code est la poésie, bien qu'un public très peu imaginatif, mais il doit quand même être lu court et doux).

Même si vous ne l'êtes peut-être pas, votre code devrait être copain copain avec les maths.

Oui, je sais - les mathématiques sont ennuyeuses et vous n'avez jamais utilisé de dérivé dans la vraie vie.

Mais…. Je promets - cela peut être très utile. C'est en fait l'outil le plus fiable que nous ayons.

Il est digne de confiance car il a une longue histoire de contributions open source et ils ont résolu la plupart des bogues dans le logiciel de base. Maintenant, les développeurs (mathématiciens) sont occupés à découvrir des choses folles comme la physique quantique.

Nous pouvons faire confiance à des éléments utiles comme la cryptographie pour sécuriser nos comptes bancaires et nos communications. Nous pouvons faire confiance à la théorie des ensembles pour appliquer le système de types de [ADD FAVORITE PROGRAMMING LANGUAGE HERE]. On peut même aller jusqu'à faire confiance à l'algèbre linéaire pour optimiser son parcours sur Google maps et ChatGPT pour rester bêtes.

Il est important de se rappeler que derrière toute l'interface utilisateur sophistiquée et l'écran brillant, nos ordinateurs ne sont que cela ; informaticiens.

Si vous supprimez toutes les complexités, vous vous retrouvez avec les rudiments de l'addition et de la soustraction.

Peut-être, juste peut-être… il y a un moyen de faire passer tout ce pouvoir dans notre propre code.

Plongeons un peu plus profondément

Je vais faire une supposition folle et supposer que vous (le lecteur) êtes familier avec la programmation orientée objet,

Et… J'irai aussi jusqu'à deviner que vous avez entendu parler de la programmation fonctionnelle - mais décidé que c'était quelque chose à apprendre un autre jour.

Si vous êtes dans ce camp, vous n'êtes peut-être pas conscient de la beauté et de l'élégance des langages de programmation qui suivent de plus près la sémantique des mathématiques traditionnelles.

Nous (les gens normaux) sommes gâtés par les abstractions fournies par les langages traditionnels. Nous nous attendons à pouvoir créer des variables quand nous le voulons et à construire des flux de contrôle complexes avec des tours de ifetelse

Nous (les gens normaux) devrions cependant prendre note de notre contrepartie de programmation fonctionnelle plus intelligente.

Il y a des superpouvoirs cachés dans des langages simples et contraignants. Ils fournissent des méthodes prouvables ( ⚡️ alimentées par les mathématiques ) pour montrer que votre code couvre tous les cas, ou qu'il peut être divisé en éléments de travail discrets qui peuvent être répartis sur des machines infinies.

L'infini et les preuves sont des idées difficiles pour le programmeur moyen, mais tout mathématicien les mange au petit-déjeuner.

Par exemple, l'un de ces super-héros dans la vidéo ci-dessous, montre comment la modélisation d'un système peut fournir des moyens de trouver des instructions étape par étape pour exploiter des bogues complexes incroyables sans regarder une ligne de code réel

Le secret réside dans la puissance des mathématiques formelles appliquées à la conception de systèmes.

Si elles sont appliquées correctement (et non, cela ne nécessite pas de tout réécrire dans un langage fonctionnel), vous bénéficiez gratuitement de tous les avantages des mathématiques.

Ces avantages incluent, mais ne sont pas limités à

  • générer automatiquement un test pour chaque utilisation possible de votre programme
  • explorer les implications de l'ajout de composants ou de systèmes de suppression à votre application
  • être sûr à 100% que le code fonctionnera. Vous voulez être vraiment sûr que votre logiciel de train d'atterrissage d'avion fonctionne, n'est-ce pas.
  • d'autres choses plus complexes que les intervenants de ces vidéos peuvent vous apprendre. Oh et si vous voulez vraiment apprendre cela, consultez TLA +

Peut-être que nous pouvons utiliser certains de ces concepts incroyablement ennuyeux pour rendre notre code incroyablement étonnant.

un bon code devrait aspirer à avoir des idées si concrètes que ces mêmes idées restent vraies dans plus de 1000 ans

Pathagotem a mis au point un excellent logiciel pour les triangles en ~ 570 avant JC…. c'est comme il y a 1500 ans !

Peut-être devrions-nous apprendre ou utiliser les mathématiques lorsque cela est possible - c'est la meilleure façon pour nous, les humains, de savoir comment exprimer des abstractions durables.

4. écrit pour les humains et non pour le matériel

Assez d'accord sur les trucs de maths. Lorsque nous parlons de logiciels, autant que nous essayons d'éviter les humains. Ils entrent toujours dans le mélange.

Parlons des humains. Comment les humains s'intègrent-ils ?

Eh bien… ce sont eux qui veulent le logiciel en premier lieu, et en fait ce sont eux qui ont inventé ces langages.

De plus, ce sont eux qui se soucient de tout cela - les ordinateurs n'ont pas d'opinion sur le code qu'ils exécutent.

Les gens font. Les gens définissent ce qui « marche » et ce qui ne marche pas.

Donc - je suppose que nous devrions tout orienter vers les droits de l'homme ?

Oui! et cela ne signifie pas seulement que nous avons besoin de jolies interfaces utilisateur et d'applications mobiles ergonomiques.

Nous devons étendre l'humanité dans le développement de logiciels. Nous devrions ressentir cela à plusieurs niveaux.

L'humanité devrait être dans l'expérience du développeur à tous les niveaux. Voici quelques questions centrées sur l'humain.

  • Les gens sont intégrés aux bases de code. Votre documentation facilite-t-elle cela?
  • Combien d'outils/commandes ou d'étapes de configuration spéciales dois-je suivre ?
  • À quoi ressemble l'ajout d'un nouveau test ? une nouvelle fonctionnalité ?
  • Combien de frameworks/langages votre projet impose-t-il ? Pourrait-il être moins?
  • Combien d'efforts faut-il pour passer d'une version entièrement nouvelle à une version entièrement en production ?
  • A quoi ressemble la rupture ? et devrai-je me réveiller pour le réparer ?

Mais une petite équipe de bons développeurs est supérieure à la somme si c'est des parties (quand c'est fait correctement).

Alors, comment pouvons-nous obtenir un excellent code d'une équipe ?

Certaines solutions sont plus faciles que d'autres. Par exemple, une solution simple mais efficace consiste à tout standardiser - supprimer toute personnalité des contributions individuelles.

Bien que cela semble dur - un système solide aura des façons/types/modèles spécifiques pour faire les choses. Il devrait y avoir très peu de personnalisation et de créativité dans la syntaxe du code.

Pourquoi est-ce une bonne chose ? Cela soulage considérablement la charge mentale du développeur. S'il y a une « façon » de faire quelque chose, alors cela devrait être fait de cette « façon ».

Cela déplace efficacement la solution du niveau du code au niveau de la structure (mentionné précédemment). Puisque nous devons nous appuyer sur des décisions et des modèles au niveau du système plutôt que sur des modèles sur mesure.

Plus simplement, tous les développeurs doivent partager des types communs. Cela supprime la personnalisation et facilite l'intégration de divers travaux de développement.

Cette idée devrait s'étendre bien au-delà des types et autant de concepts peuvent être efficacement standardisés au niveau du système, plus votre code sera grand.

un bon code est si bien écrit que les contributions de différents membres de l'équipe sont souvent indiscernables des autres parties de la base de code. De plus, vous ne devriez pas être en mesure de voir où une personne a commencé et où une autre a terminé.

Dans la vidéo suivante, les stratégies pour constituer des équipes et augmenter la productivité à mesure qu'un système devient plus complexe sont explorées en détail.

C'est un sujet fascinant puisque les idées de conception de systèmes complexes sont bien en dehors de la portée des ordinateurs et touchent à des phénomènes naturels comme la biologie animale/végétale, les interactions sociales et les planètes.

Nous, simples mortels/développeurs, détenons beaucoup de pouvoir entre nos mains. Nous pouvons construire des tas massifs de conneries complexes et inutiles - et avec ces mêmes mains, nous pouvons construire nos propres systèmes dynamiques complexes pas trop différents de la planète sur laquelle j'écris ceci.

Jusqu'à la prochaine fois, continuez à coder, répandez l'amour et la paix ✌️