Ma conception (très) personnelle du développement

Ce qui me meut

Dans cet article, je vais essayer de compiler un certain nombre de principes de développement que j’ai tiré de 10 ans de Direction Technique, en prenant parfois un malin plaisir à prendre le contre-pied de certains autres principes, parfois érigés comme des dogmes du métier de développeur.

Je dois d’abord, faire une petite parenthèse personnelle : en analysant ma pratique quotidienne du développement, j’ai pu constater que j’avais quatre caractéristiques qui conditionnaient ma façon de travailler :

  • impatience/rapidité
  • curiosité
  • émerveillement
  • expérience (autre façon de dire que j’ai eu plus souvent l’occasion de merder que les ptits cons jeunes développeurs)

Alors, pour paraphraser Tyler Durden

Comment ce que l’on possède [comme caractéristiques] finit par nous posséder ?

La rapidité comme mode de développement

Beaucoup de développeurs ont tendance à confondre perfectionnisme et lenteur, alors, certes, lorsqu’on prend plus de temps, on a tendance à écrire un code plus propre, mais est ce une bonne chose ?

Trouver une aiguille dans une botte de foin : facile, il suffit de faire bruler le foin puis d’utiliser un aimant

Je pars toujours du principe qu’il est important d’obtenir le plus rapidement possible une solution aux problèmes qui sont posés par le développement, pourquoi ? tout simplement parce que très fréquemment le problème que vous devrez résoudre n’est pas celui qui vous a été posé

Quelques exemples :

  • Vous devez coder un système de panier sur un site marchand, c’est en fait l’API de paiement qui s’avérera pourrie
  • On vous demande d’optimiser la montée en charge d’un site, vous penserez threads, systèmes asynchrones, c’est en fait le serveur qui est obsolète
  • Vous devez corriger un code PHP, en fait, c’est en Python que vous devriez coder :D

Nous, développeurs, avons été surentraînés, lors de nos études, à résoudre des problèmes complexes. Mais nous oublions souvent qu’ils sont posés par d’autres développeurs, généralement bien plus experts que nous et qui posent le problème correctement.

En dehors des études :

Ce ne sont pas des problèmes qui nous sont posés mais des besoins qui sont exprimés avec l’apparence d’un problème.

Donc :

  • Dans chaque problème (exprimé par un non-expert), il faut d’abord identifier le besoin
  • Pour répondre à ce besoin, il faut trouver le chemin le plus rapide
  • Ensuite seulement, nous pouvons retrouver nos bonnes habitudes et trouver une solution plus élégante.

En résumé :

Pour résoudre un problème, le plus simple est souvent de faire disparaître le problème

Le but est plus important que le chemin

J’aime les aphorismes :)

Obtenir rapidement un résultat est, on l’a vu, une manière de reformuler un besoin.
Le développement ne suit pas des routes toutes tracées : on identifie un premier chemin, puis on en trouve un meilleur, etc…

Atteindre souvent le but est pour moi le principe fondamental du développement itératif et de la plupart des méthodes agiles.

Si je ne peux pas atteindre la perfection, je vais aller ailleurs

Ok, ok, on fait du développement itératif, on itère, on itère, on itère… mais on arrive quand ?
Il est important de savoir s’arrêter : certaines solutions ne sont potentiellement pas atteignables (cf problèmes NP-complet et +)
Donc il est nécessaire avant même de s’attaquer à un problème de développement de définir ce qui constituera une solution satisfaisante

1 - Quand les solutions parfaites sont complexes à atteindre, les heuristiques sont souvent des solutions acceptables :p
2 - Généralement, il est préférable que la personne qui s’attaque au problème ne soit pas celle qui définit les conditions d’arrêts

Exploiter le travail des autres

Je parle bien évidemment des outils Open Source :)

En appliquant le principe classique “diviser, c’est régner”, on peut fréquemment constater qu’un problème donné est subdivisible en sous problèmes plus petits et plus simple à résoudre … et fréquemment résolus rapidement par des outils Open Source

Le hack n’est pas une sale manie

Aller plus vite, utiliser au mieux son temps, est pour moi une nécessité.
A ce titre, je n’ai aucun scrupule à coder des hacks (/verrues/code sale) : je dois juste les assumer en tant que tels et laisser les commentaires adéquats.

Ce principe, utilisé seul, est fondamentalement mauvais, il doit être complété par :

  • des tests unitaires
  • des tests de non régression
  • tous les avertissements possibles pour signaler le hack

Faire un hack, ce n’est pas grave, il faut juste s’assurer qu’il sera corrigé

La magie noire, c’est aussi de la magie

Bon, même avec toute la mauvaise foi du monde, je sais qu’il ne va pas être simple de justifier ce principe :p

En tant que Directeur Technique, il m’est arrivé de faire de la magie noire :

J’ai, par exemple, implémenté un système de cache hiérarchique en Python, qui s’appuyait sur de l’introspection de la pile d’appel de Python, codé sous forme de décorateur, qui permettait à chaque fonction appelée d’aller consulter le cache généré par ses ancêtres pour éviter de requêter la base de données pour reconstruire une information.

Ca a l’air complexe et obscur ? oui, oui, c’est de la magie noire, je vous l’avais dit

Pourquoi ai je fait ça ? Toujours pour des questions de temps : les serveurs subissaient une charge violente qui ralentissaient toutes les pages, passer par cette magie noire a permis de diviser par 10 la charge de tous les serveurs.

Bon, quelques mois plus tard, j’ai participé à la création de la calvitie de mon développeur Guru lorsqu’il a du résoudre un bug qui était caché par cette magie noire (Damien, me pardonneras tu ? ;))

La magie noire peut être pratiquée quand il n’y a pas d’autres solutions mais elle est et restera symptomatique d’une mauvaise anticipation.

Le développement est un jeu

Amis non développeurs, je dois vous avouer quelque chose : pour nombre de développeurs, le développement est avant tout un jeu, ce qui les motive, c’est la résolution d’énigmes et non écraser la concurrence, gagner le marché, se faire plein de thunes ou conquérir le monde.

Ca ne les empêche pas pour autant, d’avoir une conscience aiguë de ces faits, voire d’y adhérer, mais ce n’est souvent pas leur première préoccupation.

Dans ce jeu, la machine est à la fois le meilleur allié et le pire des adversaires

L’homme contre la machine

Le développement, c’est la confrontation de deux “intelligences”, celle de l’homme, mélange de raison et d’intuition et celle de la machine, machine de Turing, fondamentalement mécanique et aux résultats prédictibles.

La finalité du développement, c’est par, un étrange anthropomorphisme de faire “entendre raison” à la machine pour qu’elle produise le résultat attendu dans un temps minimal.

Les moyens de traduire ces idées humaines en opérations réalisables par cette machine à états, ce sont les langages de développement.

Tous les langages - Turing-complets - sont, in fine, équivalents.

Le choix d’un langage de développement est peu important, ce qui importe c’est la capacité des développeurs qui le mettent en œuvre à traduire rapidement leurs idées en programme fonctionnel

Cette dernière affirmation, volontairement choquante, présente évidemment de nombreuses limites et exceptions : dans les faits, nous savons tous que les langages ne se valent pas, en particulier en terme de performance.

L’erreur est humaine alors pourquoi mon ordinateur bugge ?

Je veux maintenant requalifier ce qu’est le développement : il ne s’agit en fait pas d’un jeu entre nous et la machine, il s’agit d’un jeu entre nous et nous-même.

Les ordinateurs ne buggent pas, c’est nous qui buggons

Je vais me refaire

La traduction de nos idées en opérations réalisables est souvent imparfaite ET/OU en traduisant nos idées, nous découvrons, des nouveaux concepts qui nous amènent à vouloir reprendre notre code et à le rendre plus générique

Le refactoring, ingrédient essentiel du développement itératif, naît d’une volonté d’abstraction. C’est un processus fondamentalement sain, mais qui doit toujours être contraint par le temps - cf première partie

La curiosité n’est pas un vilain défaut

Dans le développement, la curiosité est une vertu et un moteur pour découvrir de nouvelles façons de résoudre les problèmes.
Je suis toujours émerveillé de voir comment l’informatique mute et se réinvente en permanence.

La veille est une composante essentielle des métiers du développement. Rester sur ses acquis, c’est se faire dépasser.

Il n’y a rien de nouveau sous le soleil mais le soleil change tous les jours

Cependant, il reste des invariants :

  • L’organisation des projets
  • La modélisation des bases de données
  • Les stratégies pour obtenir du code de qualité (tests unitaires, tests de non régression)
  • L’importance critique de l’équipe de développement

Ce qui évolue, ce sont les outils, l’obsolescence n’est pas programmée, elle est développée :p

Il est quasiment possible tous les ans de remettre entièrement en cause, l’ensemble des développements que l’on a mené car un nouvel outil a absorbé, digéré et amélioré un outil plus ancien en le rendant plus pratique, plus générique et plus puissant.

On apprend à ses dépens … j’ai beaucoup appris

Je veux parler ici de la vertu des erreurs : il ne peut y avoir de curiosité sans erreurs, on ne peut pas découvrir de nouvelles technologies sans les essayer.
C’est seulement en se trompant que l’on peut apprendre et j’ai eu souvent l’occasion de me tromper par le passé, ça m’arrive toujours mais de moins en moins souvent (ou peut-être suis je en train de me tromper)

Réinventer la roue rend plus intelligent

Tout développeur connaît bien ce principe : “il ne faut pas réinventer la roue
Je crois qu’il ne faut pas prendre ce principe au pied de la lettre et qu’au contraire de temps en temps il faut réinventer la roue pour comprendre :

  • à quel point elle est utile
  • quelles sont ses limites
  • comment elle a été conçu

Réinventer la roue, permet de comprendre la roue et d’inventer une super roue.
On n’améliore pas un outil de l’extérieur, il est nécessaire de le comprendre de l’intérieur.

Le travail d’équipe

Je veux finir cet article par un sujet qui va s’éloigner un peu du métier de développeur
Il s’agit du travail en équipe et du rôle du Directeur Technique

Dans Direction Technique, il y a (roulement de tambours) Direction.
En tant qu’ancien prof de math (dans une autre vie), je me représente toujours ce terme par un vecteur, de préférence, un vecteur de vitesse :)

Le rôle du Directeur Technique est donc, basiquement, pour moi, celui de la définition de l’objectif, de la direction (on y revient) à prendre et de la vitesse à laquelle il faut y aller.

La direction doit être claire et toute l’équipe doit y adhérer.
Il est préférable de se tromper ensemble que de stagner en tirant le projet dans toutes les directions.

De toute façon, l’erreur dans les projets de développement n’est jamais totale, il y a toujours des interlocuteurs extérieurs prêt à nous rappeler quel est le besoin.
Et comme dit précédemment, l’erreur est bénéfique et permettra à toute l’équipe de gagner de l’expérience.

Ceci, une fois de plus, plaide pour choisir rapidement les technologies qui vont être utilisées et les mettre ensuite rapidement en œuvre.

Il y a autant de styles de Direction Technique qu’il y a de styles de gouvernement ou d’organisations humaines, mais le point clé qui conditionne la réussite d’un projet, c’est la connaissance du chemin à parcourir et l’adhésion ou la confiance en la capacité de l’équipe à réussir.

This is sparta !!!!

Lorsque la direction est claire, que le principe de mouvement est entériné et que le chemin est connu, même si potentiellement, ce n’est pas le bon (mais ça, on peut ne le savoir qu’après), c’est l’ensemble de l’équipe qui doit lancer le projet comme un seul homme <=> après l’adhésion, l’adhérence :p

La taille des équipes importe peu, lorsqu’un projet de développement est lancé, c’est toute l’équipe qui est impliquée, qui affrontera ensemble les difficultés et les résolvera ou qui constatera collectivement que le chemin n’était pas le meilleur et qu’un (souvent) léger repli s’impose

Le jeu de rôles

Précédemment, je parlais de l’importance de la collectivité, mais il ne faut pas confondre collectivité et uniformité.
Chaque personne qui compose une équipe de développement est un individu particulier avec son histoire personnelle et ses désirs spécifiques.

Ceux qui fantasment sur les équipes de développement et y voient une liste de ressources humaines remplaçables et interchangeables à l’envie se trompent lourdement et se condamnent à l’échec.

Je considère au contraire que dans une équipe, pour un projet donné, chacun doit avoir un rôle bien défini, le connaître et l’assumer.

J’ai souvent identifié les profils suivants :

  • Le multi-carte :
    • il est prêt à travailler sur tout ce que l’on confie et il fait avancer le projet
    • son rôle est important, car c’est lui qui génère la vitesse du projet
    • accessoirement, par le travail qu’il abat, il donne du temps aux autres profils
  • Le pragmatique :
    • son cœur balance souvent entre le désir de faire du code propre et celui de faire avancer plus rapidement le projet
    • il fait le pont entre le puriste et le multi-carte et crée de la cohésion dans l’équipe
    • c’est lui qui va définir la qualité en moyenne du projet
  • Le puriste du code :
    • le code sale le répugne
    • et souvent, pour lui, tout le code est du code sale
    • mais il évite la surchauffe de l’équipe : il empêche la confusion entre vitesse et précipitation
    • de projet en projet, il conditionne l’amélioration progressive de la qualité du code

Avoir ces 3 profils me semblent être une condition d’équilibre de l’équipe de développement et une condition de réussite des projets.

Je vais tenter de le démontrer par l’absurde, en imaginant des équipes mono-profils :

  • Equipe de multi-cartes :
    • Les projets avancent vite, le code est vite produit mais l’absence de bonnes pratiques fait que la maintenance prend de plus en plus de temps jusqu’à rendre les projets non viables
    • On trouve souvent ce type d’équipes dans les petites agences de développement qui n’ont pas encore les moyens de recruter des développeurs expérimentés et plus puristes (comprendre : chers)
  • Equipe de pragmatiques :
    • Les projets avancent correctement, le code produit est de bonnes qualité mais la qualité stagne et la société se fait dépasser par d’autres sociétés.
    • L’absence de puristes fait que les pragmatiques n’ont pas l’impression de progresser en compétences aussi vite qu’ils le pourraient et ont rapidement envie d’aller voir ailleurs
    • On trouve souvent ce type d’équipes dans les SSII, car c’est, en fait, la seule équipe mono-profil qui peut réussir un projet dans les temps (quitte à partir ensuite)
  • Equipe de puristes :
    • Les projets n’avancent pas, même si le code produit est d’excellente qualité, on se demande combien d’années seront nécessaires pour sortir le projet
    • On trouve souvent ce type d’équipes dans les start-ups (qui ont réussi à lever suffisamment de fonds :p) et qui cherchent les “meilleurs des meilleurs des meilleurs”

On est bien ensemble, non ?

Bien, la direction est claire, le projet a obtenu l’adhésion de l’équipe, a un bon rythme de croisière et l’équipe est équilibrée.

Normalement, le projet ira à son terme et sera une réussite :)

La réussite des projets est ce qui renforce la cohésion de l’équipe et la joie sera additive
Dans une équipe soudée, les erreurs seront divisées entre tous les membres et chacun prendra une part de la responsabilité


Je tiens à finir cet article en saluant l’ensemble des développeurs avec qui j’ai le très grand plaisir de travailler par le passé, qui m’ont permis d’évoluer, en cassant mes propres certitudes et dogmes de jeune, ou moins jeune, développeur et qui me permettent encore aujourd’hui de remettre chaque jour mon ouvrage sur le métier :)


Commentaires

Maxime M - il y a un an et 9 mois

Bel article, je trouve l'analyse assez juste :)

Je suis persuadé que l'expérience permet de trouver le juste compromis entre productivité et structure, et il faut avoir un certain nombre de cicatrices pour comprendre la rigueur qu'exige le développement à un niveau professionnel. On peu l'expliquer, mais sans l'avoir vécu on ne peut pas atteindre un niveau de compréhension équivalent.

Qu'en penses tu ?

Raphaël - il y a un an et 9 mois

Hello Maxime :)

Oui, tout à fait : il faut avoir en effet pas mal de cicatrices pour comprendre les risques qu'il y a à s'écarter des bonnes pratiques de développement. J'ai écrit cet article comme une invitation à l'expérimentation et en particulier à l'expérimentation de la vitesse, en prenant quelques raccourcis pour qu'au final, on comprenne plus rapidement comment résoudre un problème donné => mais le code de la dernière itération doit être le plus propre possible.

Pour le dire autrement : chercher à obtenir tout de suite un code propre est souvent contre-productif, mais, in fine le code doit être propre (selon les critères d'acceptabilité)



Ajouter un commentaire

Tous les commentaires seront modérés avant publication

Envoyer le commentaire