Mes conseils de développeur partie 2

Mes conseils de développeur partie 2

Alexandre P. dans Dev - Le 23-06-2022

Suite au précédent article où je vous parle de comment je me suis amélioré en tant que développeur. Je vous propose de continuer notre progression ensemble en parlant de ce que l'on peut faire pour devenir meilleur.

Quelques astuces pour bien progresser en tant que développeur web

Pour faire suite au précédent article sur le développement , voici encore quelques conseils pour vous améliorer en développement.

1 - Tester son code

Cela demande du temps de tester en permanence les itérations de votre code source. Mais cette étape est très importante ! Elle assure le bon fonctionnement - parcours prévu, résultat attendu - de votre code.

Il y a plusieurs façon de tester son code : les TU (tests unitaires) souvent réalisé par les développeurs eux-mêmes.

Il s'agit d'isoler une petite partie du code et tester son fonctionnement. On le fait généralement avec les fonctions que l'on peut tester directement via ses I/O (entrées, sorties). En gros on l'appelle avec des paramètres et on vérifie que la réponse est cohérente et qu'il s'agit bien du résultat attendu, ou comportement attendu s'il s'agit d'un void (fonction sans retour).

Pendant longtemps, les boîtes ont encouragé les développeurs à avoir un fort niveau de coverage, c'est à dire plus de teste sur une plus grande partie du code. Plus le coverage est élevé plus l'entièreté du code est testé. Or, d'expérience, c'est parfois contre-productif de le faire. Je dirais qu'il faut tester essentiellement les logiques complexes et avoir environ 60 à 65% de coverage est déjà largement suffisant.

Au delà, on passe surtout énormément de temps à maintenir les tests, moins à développer des features, en sachant que des langages comme Typescript (mon petit chouchou), règle déjà énormément de problèmes en amont.

Les TU restent cependant terriblement efficaces, a tel point qu'on en a fait une méthodologie de travail : le TDD (test-driven development). Ce qui signifie que l'on va commencer par implémenter les tests avant même de faire le code.

Par exemple, je dois faire une fonction qui doit multiplier un entier passé en argument par 2. Cette fonction s'appelle multPer2. Je commence par faire un test qui vérifie que le résultat est bien égal au double de mon entrée. Avec les libs de tests assez connu tel que Jest, ça donnerait cela :

describe('test libs', () => {
    it('Should multiply per 2', () => {
        var result = multPer2(2)
        expect(result).toEqual(4)
    })
})

Dans ce test, on vérifie que le résultat est égal à 4. Dans le cas contraire, le test renverra une erreur. Maintenant une fois que les tests sont prêts, je peux commencer à coder ma fonction, le but du jeu est de faire tourner les tests (automatiquement si possible) jusqu'à ce que tout soit ok.

function multPer2(inp) {
    return 2 * inp
}

Pour tester le front (des composants react par exemple) ce n'est pas si simple. En général, on utilisera des outils qui permettront de générer un fake DOM et de simuler des timers, pour les lifecycle de render (comme jest, react-testing-library, etc...). Mais ils ne sont pas simple à prendre en main, et si votre composant connait énormément de mutation d'état pour X ou Y raison, cela risque d'être difficile à tester. Mais rassurez-vous il y a des outils spécifiques pour ça : les tests E2E.

Les tests E2E (end-to-end) sont généralement implémentés (code ou no code) par les QA testeurs, donc des profils dédiés à ce type de tests. Mais dans certaines équipe il n'est pas rare que ce soit les développeurs eux-mêmes qui implémentent les E2E. Aujourd'hui, le marché propose de nombreux outils intéressants comme : Cypress ou Playwright et il y a de quoi faire !

Ou au moins testez à la main ce que vous faites, c'est un minimum. De même, si vous relisez la PR d'un collègue, prenez le temps de réellement tester les choses et ne validez pas uniquement en ayant lu sur GIT à moins que ce soit du code très simple CSS, etc... Prenez le temps de le faire.

2 - Anticiper le comportement du code

Lorsque vous prenez de l'expérience, vous serez en mesure d'anticiper plus facilement sur la complexité de ce que vous allez implémenter. Instinctivement, vous saurez d'avance :

  • quand est-ce qu'une implémentation risque de vous donner du fil à retordre
  • quand est-ce qu'une valeur en entrée risque de changer
  • pourquoi le code risque de ne pas s'exécuter
  • pourquoi une partie de votre code est exécuté avant ou après telle ou telle action
  • pourquoi le résultat obtenu risque de ne pas être correct

Maintenant, utilisez votre expérience pour prévenir ce genre de problèmes. Puisque vous savez que cela peut arriver, et que vous êtes en mesure de comprendre pourquoi. Il est possible de mettre en place des gardes-fous.

Votre expérience ne doit pas vous servir uniquement à coder plus vite, mais surtout à coder mieux.

J'ai des règles d'organisation et d'anticipation qui globalement fonctionnent très bien et me permet de dormir sur mes deux oreilles.

Voici ma méthodologie :

La base :

  • J'organise toujours mon code de manière à savoir exactement où est positionné telle ou telle brique. Il faut que je n'ai pas à réfléchir pour retrouver un composant, une lib, une page, les configs, etc...
  • Je n'inclus jamais les clés API, tokens et les endpoints au code source, car le code n'est pas hébergé sur ma propre machine. Dans un data center qui sait ce qui peut arriver ? Les sociétés comme Github, Bitbucket et autre ne sont pas à l'abris d'un hack de la couche 0... (l'humain, les employés eux même !). J'utilise l'environnement sans versionner le fichier .env

Plus technique :

  • Je pars du principe que tout ce qui est externe a mon code n'est pas fiable, donc je redouble d'effort sur les vérifications de ces données. Par exemple une API peut ne pas répondre, changer de format de réponse, etc..., donc, je prends les devant et je vérifie que je dispose des éléments qui me permette de continuer à processer, dans le cas contraire, je m'arrête avant de générer des erreurs ou faire crasher mon programme.
  • Lorsque je code du frontend, je réduis au maximum le nombre de composants qui font des calculs ou manipulent des données. En général, je crée le maximum de dumb components, destinés uniquement à faire de l'affichage. Et j'effectue des appels API et des opérations uniquement dans certains fichiers ciblés. Cela me permet en cas de dysfonctionnement de savoir exactement où effectuer une action.
  • Je factorise au maximum les utilisation commune ou les schéma commun dans mon code, cela me permet de réduire mes efforts en cas de modification car plusieurs éléments seraient modifiés simultannément.
  • Je dissocie la partie API (récupération de données) de la partie exploitation de ces données, afin de ne pas avoir de comportement trop spécifique sur ma brique la plus commune. Par exemple, je traite la réponse d'API et affiche des toasters etc... à l'endroit ou j'appelle ma librairie d'API et pas directement dans la lib.
  • Sur les gros projets, je distingue fortement le traitement synchrone du traitement asynchrone. C'est à dire que je préfère garder sur mon API ce qui est vital pour que l'utilisateur puisse avoir le maximum de confort (temps de réponse courts, données essentielles, etc...). Et toute la partie traitement (stats, compteurs, cache, etc...) je le fais via d'autres threads que j'appelle les Workers.
  • Je privilégie toujours la lisibilité plutôt que la sur-optimisation. Biensûr dans certains cas, je préfère optimiser afin de ne pas trop multiplier les instructions et ralentir le code. Mais si cela rend le code plus lisible pour mes collègues, je prends le temps de montrer certaines opérations de manière plus explicite afin d'être plus clair et plus facile à appréhender.

3 - Surmonter ses peurs en programmation

A chaque fois qu'un sujet technique vous angoisse, car il vous parait complexe, soyez sûr que si vous le maîtrisez vous apprendrez quelque chose.

Les outils à disposition des développeurs n'existent pas par hasard. Très souvent, ils sont le fruit de recherches et de travaux destinés à simplifier la vie du développeur.

Par exemple, combien de condition "if" vous faut-il pour remplacer une seule et unique RegExp ?

Combien d'indentation vous faut-il utiliser dans une série de Promise, au lieu d'utiliser l'async/await ?

Une chose est sûr, cela m'a toujours été bénéfique d'apprendre de nouvelles choses. Et cela devrait être un sujet excitant et pas repoussant.

Prenez le temps d'appréhender et de tester les nouveaux outils et les nouvelles méthodos. Si les gens en parlent, c'est qu'il y a forcément un intérêt qui a été décelé par développeurs.

Le plus simple est d'intégrer cet apprentissage à votre routine de veille technique. Une partie de votre temps doit impérativement être destiné à la veille technique et doit vous permettre de tester ces outils.

Même si, vous ne comptez pas vous en servir à terme, il est intéressant de savoir dans quelle situation, cela pourrait vous servir. De même, je vous recommande d'utiliser un outil de note, et de toujours noter une description, un exemple et tagger la note afin de la retrouver plus tard.

Votre apprentissage doit vous servir à quelque chose, car si vous ne faites que lire sur le sujet, votre lecture ne vous aura servi à rien si vous n'en avez pas tiré une information.

4 - Intéressez vous aux patterns

Il y a des méthodologie partout et sur tout. Nous cherchons sans cesse le moyen de nous organiser, de faciliter la collaboration, c'est pourquoi, des chercheurs créent chaque jour de nouveau outils, des patterns afin de rendre cela possible.

Qu'est-ce qu'un pattern ?

Un pattern est une méthode de travail qui va organiser comment implémenter notre code afin de répondre à une ou des problématiques (découpage des tâches, compatibilité, communication, etc...)

Par exemple un Pattern d'organisation de projet MVC (Model, Vue, Contrôleur) cherche à isoler la complexité de chaque ensemble d'éléments (utilisateurs, produits, ventes, paiements, etc...), en le découpant en 3 axes. Si nous voulons utiliser le pattern MVC pour gérer des utilisateurs, nous ferons :

  • le model qui décrit de quoi est composé un utilisateur, ses champs (nom, prénom, age, etc...)
  • la vue, c'est à dire comment on va afficher un ou des utilisateurs
  • le contrôleur qui fera le lien entre le modèle, donc l'objet utilisateur au sens code et la base de données. En général le model décrira les actions qui manipulent un modèle utilisateur (créer un utilisateur, mettre à jour un utilisateur, etc...)

Ce pattern a plusieurs avantages, son découpage permet non seulement de réduire la complexité, mais de séparer le travail en plusieurs tâches réalisables par plusieurs collaborateurs.

Dans notre cas, un intégrateur peut se charger de toutes les vues et un développeur peut se charger des Modèles et Contrôleurs...

Et il existe des milliers de patterns intéressants à connaitre qui permettent de régler beaucoup de problèmes. Certains patterns sont mêmes propre à des langages spécifiques, tel que l'Event-Driven Pattern que l'on peut faire essentiellement en JS, C# ou Java.

Bien sûr il y a souvent des adaptations de certains pattern dans différents langages mais parfois certains langages s'y pretent mal de par leur conception.

Ainsi, je vous recommande d'en savoir plus sur les patterns afin de toujours faire le choix le plus éclairé dans une situation donnée.

Conclusion

Globalement, le fait de répéter les mêmes choses chaque jour et de s'intéresser au développement vous aidera naturellement à progresser.

Ce que je vous recommande pour mettre en place quelque chose de concret est de se donner 1 heure par jour de travail approfondi sur un sujet. Que ce soit une nouvelle techno, un pattern, une librairie etc... Se donner 1 heure même en deux session de 30 minutes (matin et soir) c'est une différence énorme sur une année (plus de 200h). En sachant qu'à chaque heure que vous passez à tester, ou réaliser quelque chose, vous devenez meilleur.

A vos claviers ! 😃

#conseils#programmation#progresser

user picture
Alexandre P.

Développeur passionné depuis plus de 20 ans, j'ai une appétence particulière pour les défis techniques et changer de technologie ne me fait pas froid aux yeux.