Industrialisation - Abstraction (Partie 1)

24/08/2018

Qu'est-ce qu'on entend par industrialisation ?

Qu'on soit soit free, dev dans une SSII, ou stagiaire en agence web, nos développements ont une valeur et un coût. Et je ne vais rien vous apprendre en vous disant que le meilleur moyen de rendre votre développement le plus lucratif possible, c'est d’augmenter la valeur de votre production, et d’en baisser les coûts.

Mais alors, augmenter la valeur, ça veut dire passer plus de temps à peaufiner ? Diminuer les coûts ça veut dire baisser son salaire ? Travailler plus pour gagner moins? Heureusement non, dans notre domaine dématérialisé, on a la possibilité de gagner du temps facilement et d'augmenter la qualité pour un moindre coût. Et si une partie de cet effort est liée aux outils que nous utilisons (imaginez nos journées sans copier/coller), ce n’est pas suffisant, la base est dans la réflexion qu'on apporte à nos devs. C'est bien en combinant ces deux aspects, outils / conception, qu'on trouve le principe d'industrialisation : comment produire mieux en moins de temps.

Et il faut bien prendre conscience que ce qui coûte le plus cher dans un dev, c'est le développeur, c'est son temps (la connexion internet, la licence PHPStorm, les posti-ts et les handspinners sont négligeables). C'est pourquoi, en dehors de la logique d’entreprise, un développeur se doit (à mon humble avis) de penser “industrialisation”. Le mot peut faire peur et un peu ringard (au moins aussi ringard que le mot ringard), notamment à certaines personnes qui considèrent les développeurs comme des artistes, mais c'est cependant un concept simple, efficace et indispensable. En gros, “il faut tout faire pour en faire le moins”.

 

Le cas concret

Il faut être honnête, même si l’idée est simple et qu’on vous a déjà rabattu mille fois les oreilles avec ça (dans les tutos, durant les formations, en entreprise ou autre), la mise en oeuvre et la réflexion qui en découle est nettement moins évidente en pratique.

Et pour cause! Dans le monde du business, on a des cas métiers concrets. Par exemple, partons du principe qu'une application de fruits et légumes existe déjà et qu'on vous demande une évolution, on vous passe une commande qu’on va appeler “Ananas“ : “Quand on appuie sur le bouton rouge, l'ananas se découpe en cubes”. Et cette commande a été vendue, il faut qu’elle soit rentable, donc vous avez chiffré un temps de dev qui correspond ni plus ni moins à la commande. Vous allez livrer dans les temps et satisfaire votre client (voire même votre utilisateur), parce que votre développement correspond exactement à la demande. Et en plus, comme vous développez bien (parce que oui, vous développez bien, on le sait ;) ), il n’y a aucun bug, aucune anomalie, quand on appuie sur le bouton rouge, notre ananas se découpe en cubes… Félicitations !!

 

Le problème est un peu là… Vous développez trop bien, et le client est content, donc 12 mois après, il passe une deuxième commande, la commande “Pomme” : “Quand on appuie sur le bouton bleu, la pomme se découpe en boules”. Rien que par cet énoncé, on se rend bien compte de la similarité des deux commandes, cependant ce n’est pas tout à fait la même fonctionnalité qui est demandée.

On a donc plusieurs problèmes :

  1. Le client a en tête que la commande “Pomme” est similaire à la commande “Ananas”. Il n’est donc pas prêt à payer la même somme que pour la première commande. Et à sa place, on aurait tous le même réflexe : Pour une commande similaire, la phase de réflexion et de production ne doit pas être identique la deuxième fois. L’expérience a un coût, certes, mais il est moins élevé que la recherche / réflection / conception.

  2. Ca fait 12 mois que la commande “Ananas” a été livrée, de l’eau a coulé sous les ponts, vous ne savez plus comment ça a été fait. Vous risquez de devoir repasser du temps d’analyse pour comprendre ce que vous allez devoir modifier.

  3. Quoi qu’il arrive, même si vous êtes le meilleur développeur que vous connaissiez, n’importe qu’elle modification d’une fonctionnalité existante, peut entraîner un dysfonctionnement… Et ça, personne n’en veut… Vous ne voulez pas prendre le risque de détériorer la commande “Ananas” au moment où vous allez livrer la commande “Pomme”.

  4. Et là, c’est le pire scénario… Google a tellement aimé votre développement sur l’ananas que vous avez quitté votre ancienne entreprise pour vous installer dans la Silicon Valley (adieu la (ou le) secrétaire sexy, et bonjour le compte Paypal rempli). Et aujourd’hui, personne n’est en mesure de comprendre ce qui a été fait il y a 12 mois, pour reproduire la fonctionnalité de la commande “Ananas”, et c’est un autre développeur qui sera chargé de mettre la main dans le cambouis.

 

La solution

Je ne vais pas aller plus loin dans la description des conséquences de ces 4 problèmes. Toujours est-il qu’il est facile de comprendre que tous ces inconvénients auraient pu être évités si la première commande “Ananas” avait été conçue de manière plus abstraite. Et c’est bien là le problème du marché, c’est que le point d’entrée d’une commande est un besoin concret. C’est logique, votre client a un besoin en relation avec son métier, à un instant T.

 

Mon but n’est pas de rappeler ce qu’est la couche d’abstraction (parce que j’imagine que vous le savez très bien). Tout développeur sait ce que c’est, et sait comment la mettre en oeuvre (peu importe le contexte technique). L’intention ici est de rappeler l’importance pour un développeur de décontextualiser ses développements. C’est la base de l’industrialisation.

Tout développeur est confronté dans sa vie professionnelle à ce genre de cas. Et il est désagréable pour tout le monde et va probablement créer des points de tensions à différents niveaux du projet :

  • le client qui peut facilement perdre confiance alors que tout allait bien initialement

  • le chef de projet qui doit organiser le développement sans connaissance technique et qui doit gérer le besoin du client en tenant compte des limites financières et qui doit gérer le développeur qui va intervenir.

  • l’utilisateur qui risque de voir son expérience dégradée en cas de bug (le risque étant accru)

  • le développeur (que ce soit le développeur initial, ou un autre), qui va devoir “re”-faire un développement déjà existant.

 

Dans le cycle de vie d’un projet, aucun de ces acteurs ne doit être négligé. Un projet est un service, quel qu’il soit, et un service dégradé peut entraîner de la frustration, de la perte d’utilisateur, une dépression, etc..

Il est donc un peu de notre responsabilité, nous développeurs, de prendre de bons réflexes et de mettre en place aussi tôt que possible une réflexion abstractisée (je ne crois pas que ce mot existe). C’est à dire que les éléments métiers de la commande doivent être complètement décontextualisés.

Dans notre cas précis, dès la commande “Ananas”, vous développeur, vous auriez dû distinguer différents niveaux d’abstraction : 
Niveau concret : Quand on appuie sur le bouton rouge, l'ananas se découpe en cubes

Abstraction niveau 1 : Quand on appuie sur le bouton A1, B1 se découpe en C1

Abstraction niveau 2 : Quand A2, B2 devient C2

 

Dès lors, on peut appliquer un comparatif de temps sur l’application technique de ces 3 niveaux de conception. Si on part sur une unité qui correspond au centième de temps de développement de la première commande “Ananas” au niveau concret, on obtient la comparaison suivante :

 

 

commandes

Niveau concret

Abstraction niveau 1

Abstraction niveau 2

     
 

commande Ananas

100

130

145

commande Pomme

75

(on ne refait pas tout, mais les évolutions et les risques demandes une attention particulière)

30

(on n’a qu’à ajouter de nouveaux éléments métiers, pas de risque, pas de modification de l’existant)

30

(on n’a qu’à ajouter de nouveaux éléments métiers, pas de risque, pas de modification de l’existant)

Cumul

175

160

175

 

A noter, que plus l’expérience du développeur augmente, plus le ratio entre le temps de réalisation en Niveau concret, et les différents niveaux d’abstractions diminue. Ici, on voit bien dès la deuxième commande que le temps cumulé est nettement avantageux avec un faible niveau d’abstraction.

 

Maintenant, admettons que le client passe une 3ème commande “Patate” : “Quand on survole le bouton vert, la patate se transforme en frites”. Ici, on est encore dans la lignée des commandes précédentes, cependant on a de petites différences. Encore une fois, ces petits différences, le client n’entend pas les payer au prix de la première commande, et probablement pas au prix de la deuxième non plus. On obtient donc :


 

 

commandes

Niveau concret

Abstraction niveau 1

Abstraction niveau 2

     
 

Ananas

100

125

133

Pomme

75

on ne refait pas tout, mais les évolutions et les risques demandes une attention particulière

30

on n’a qu’à ajouter de nouveaux éléments métiers, pas de risque, pas de modification de l’existant

30

on n’a qu’à ajouter de nouveaux éléments métiers, pas de risque, pas de modification de l’existant

Patate

60

on gagne en expérience, mais on n’a toujours pas anticipé les futurs commandes...

45

on gagne en expérience, mais on doit effectuer quelques modification sur le coeur du développement, il faut donc prendre en compte les risques.

20

on gagne en

expérience et on n’a qu’à ajouter de nouveaux éléments métiers

Cumul

235

200

183

 

Pour aller plus loin dans l'exemple, je vous propose un autre tableau qui montre bien les écarts qui se créent en fonction du nombres de commande plus ou moins similaires ici.

Quel niveau d’abstraction ?

Dans ce cas, on voit bien la corrélation entre le nombre d’évolutions possibles et le coût final des développements. Effectivement, si le projet s'était arrêté à la première commande, le niveau de réflexion concret aurait été plus rentable. De même, si le projet s’était arrêté à la deuxième commande le niveau d’abstraction 1 aurait été suffisant. Enfin, au-delà de la 3e commande c'est le niveau d'abstraction 2 qui est bénéfique.

Tout le gain de l’industrialisation va effectivement se porter sur le nombre d'itérations des potentiels évolutions d'un dev sur un projet. Sur un projet ? Et non, pas forcément sur un seul projet. Ici je parle d’un cas où la fonctionnalité n’est présente que sur un seul projet, mais potentiellement vous serez à même de devoir porter ce dev sur un projet différent. Et là le niveau d’abstraction le plus profond sera encore plus bénéfique.


 

Pour résumer, il ne faut pas forcément partir d’un principe doctrinal comme quoi tout développement initial doit être fondamentalement abstractisé (je sais, ça n'existe toujours pas). Le choix du niveau de conception dépend de plusieurs choses :

  • La durée de vie du projet

  • Le potentiel adaptation du développement

  • La potentielle duplication du développement dans d'autres contextes.

 

En clair la notion d’abstraction devient de plus en plus rentable lorsque le développement évolue dans le temps, subit des aménagements, est réutilisé etc…

Et cette abstraction est coûteuse lorsque le dev s'avère être un one shot.

La prise de décision concernant le niveau d’abstraction à apporter incombe à nous certes, mais elle ne doit pas être décorréler du contexte, c'est là le paradoxe. Il faut connaître la vie du projet, anticiper ses évolutions, connaître les besoins globaux du clients afin de déterminer quelle est le meilleur niveau de conception à apporter à son dev. Et ça, vous, développeur seul, vous ne pouvez pas le faire correctement. Vous devez vous renseigner auprès du client, auprès du chef de projet le cas échéant, afin de connaître le projet sur lequel vous allez intervenir. C'est le lourd fardeau du développeur.

 

Ajouter un commentaire

HTML restreint

  • Balises HTML autorisées : <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et les adresses courriel se transforment en liens automatiquement.
Votre email ne sera pas publié mais permettra à l'administrateur de vous recontacter en cas de problème