C’est l’histoire d’un projet…
C'est l'histoire d'un projet, pas plus complexe que d'autres, pas plus simple non plus : une application qui s'interface avec une base de données et 2 systèmes tiers. Du classique du point de vue technique et architecture, du standard également du point de vue management : il faut tout faire pour hier et il y a beaucoup à faire...bref, "ca va être chaud!" comme disent souvent les développeurs mais personne ne le crie trop fort.
Alors on "staffe", on monte à 40 personnes, on spécialise les gens, on contractualise entre les équipes. Les équipes s'organisent en pools, répondant à certaines demandes puis redispatchant d'autres demandes à d'autres pools. Un flux de demandes s'organise, certains pools chauffent et deviennent le "goulot d'étranglement", un stock se crée en amont alors que les équipes en aval attendent...Dès lors et pour ces pools en surchauffe, l'important devient l'urgent, il faut choisir parmi l'urgent pour répondre à l'immédiat, switcher de tâches en permanence et au final, la chaine globale ralentit. En complément, les reportings commencent à virer au rouge dans les premiers niveaux de management. Mais au fur et à mesure de l'escalade de ces mêmes reportings dans la hiérarchie, ces derniers virent au vert tant et si bien qu'en "haut" : tout va bien.
Puis approche la date fatidique de la mise en production : c'est dans deux mois. La recette démarre à peine et a été retardée par les intégrations fastidieuses et douloureuses des différentes briques. On est en droit de se demander si la contractualisation entre les équipes n’est pas un élément supplémentaire de la complexification de l’intégration : il manque certains paramètres obligatoires, les dates ne sont pas dans le bon format, les code erreurs partiellement interprétés… Quoiqu'il en soit, la recette détecte plus d'anomalies que la capacité des équipes de développement à les résoudre et tout n'est pas encore testé.
Alors on "renforce" les équipes. Une équipe pour corriger les anomalies, une autre équipe, localisée sur un autre plateau, pour finir les développements, une troisième équipe se concentre sur l'intégration entre les briques. Mais c’est oublier que ces équipes partagent la même souche de code et que les évolutions des uns auront des « impacts » sur les corrections des autres.
Bref vous connaissez la suite (les développeurs ont travaillé la nuit et le samedi) et la fin (la date de livraison a été légèrement repoussée et le scope initial revu à la baisse), mais au final, grande magie de l’informatique, l’application a finalement été livrée et fonctionne plutôt bien !
C'était il y a quelques années, j’avais l’impression que c’était normal et que c’était la vie de tout projet. Depuis j'ai lu et discuté avec pas mal de monde ce qui me permet aujourd'hui de voir cette histoire sous un angle différent (à défaut de changer le monde…) :
Absence de priorisation ou le "il faut tout faire"
A ce titre je vous livre une citation de Tom DeMarco
You say to your team leads, for example,“I have a finish date in mind, and I’m not even going to share it with you. When I come in one day and tell you the project will end in one week, you have to be ready to package up and deliver what you’ve got as the final product. Your job is to go about the project incrementally, adding pieces to the whole in the order of their relative value, and doing integration and documentation and acceptance testing incrementally as you go.
En somme : se mettre en position de livrer demain. Au delà des réelles problématiques techniques, organisationnelles, cela nécessitera notamment la volonté de construire le logiciel de façon incrémentale. Cela demandera très certainement de limiter la contractualisation entre les équipes et organiser des équipes non pas sur des applications, des technologies ou des tâches de type "bug fix" mais sur des fonctionnalités métier. Les équipes devront également regrouper plusieurs compétences et devront être responsables de la bonne marche de la fonctionnalité dans son ensemble. Cela demandera également de faire des choix : qu’elle est LA fonctionnalité qui doit être disponible. A titre personnel, je suis de plus en plus convaincu que ce mode de fonctionnement est d'autant plus important dans des environnements où il faut "tenir la deadline".
Pression du management ou la culture de la peur
Dans Slack, Tom DeMarco expose certaines caractéristiques d'une culture de la peur :
...among the characteristics of the culture of fear organisation are these: - it is not safe to say certain things (e.g. I have serious doubts that this quota can ne met)... - goals are set so aggressively that there is virtually no chance of achieving them - Power is allowed to trump common sense ...
Lorsque j'imagine un management par la peur, j'imagine un boss un peu dictateur, physiquement impressionnant qui interpelle ces collaborateurs depuis son bureau en tapant du poing sur la table...une belle caricature en somme. C'est un peu plus insidieux que cela semble-t-il. et il faut bien avouer qu'il existe des contextes où les opérationnels subissent de telles pressions, où il est difficile de remonter des alertes, où les deadlines sont positionnées indépendamment de la capacité à faire des opérationnels et où, au final, ces derniers subissent une pression issue des engagements pris par leur manager vis-à-vis des niveaux organisationnels supérieurs. Identifier le "problème" est un premier pas. Mais comment le résoudre? Que faire lorsqu'un manager n'entend pas les risques et refuse de voir l'inévitable : il faut prioriser et négocier le contenu pour tenir la date ou bien changer la date. La tâche est loin d'être évidente et la meilleure réponse trouvée à ce jour reste le "bon vieux" backlog associé à un Burndown Chart. Il présente, à mon sens, plusieurs avantages dans ces situations : 1/ consolider l'ensemble des tâches (techniques, fonctionnelles...). Ces tâches peuvent bien entendu être regroupées par Use-Cases ou fonctionnalités. 2/ partager et faire partager l'ensemble de ces tâches à l'ensemble des acteurs du projet. Formulé autrement, rendre visible l’immensité du reste à faire 3/ rendre visible la date d'atterrissage et faire prendre conscience aux managers qu'il est nécessaire de prioriser et de choisir 4/ rendre visible les ajouts de tâches qui décale nécessairement la date d’atterrissage
A quelques semaines de la mise en production et alors que l'organisation en place chauffe, décision est prise de rajouter de la main d'oeuvre
La loi de Brooks date de 1975 (je n'étais pas encore né) et annonce
adding manpower to a late software project makes it later
. On l'a tous remarqué et pourtant force est de constater que l'on a toujours tendance à rajouter de la main d'œuvre pour tenir les délais plutôt que de changer le périmètre et conserver une taille d'équipe adaptée. Brooks justifie son adage par deux points. Le premier est la nécessaire montée en compétence des nouveaux arrivants qui sera consommateur de temps pour les personnes en place. Le second est un mythe qui consiste à croire que les tâches de développements peuvent être segmentées à la demande, sous-estimant ainsi le caractère intellectuel de la tâche de développement et la communication inter-personnelle nécessaire aux développements. On peut de plus ajouter des difficultés liées à l’organisation des développements et au fait de partager une souche de code unique entre de nombreux développeurs. Autant de freins qui ralentiront au final les équipes. A ce titre et toujours dans Slack, Tom De Marco parle de ce qu'il appelle l'overstaffing et dit :
meeting the deadline is not what this is all about. What this is about is looking like you are trying your damnedest to meet the deadline. In this age of "lean and mean" it is positively unsafe for you to run the project with a lean (optimal) staff.
Un point de vue intéressant...
"everything fails all the time". Pourquoi ne pas jouer avec et arrêter de l'ignorer?
Alors comme toujours la critique est aisée, l'art difficile mais il faut bien constater que les mêmes erreurs semblent se répéter et des alternatives (qui auront, soyons en sûr, d'autres défauts et d'autres limitations) rarement tentées. "Risk Management is a discipline of planning for failure" (Slack, Tom De Marco) et c'est peut-être là que le bât blesse. "everything fails all the time" affirme Werner Vogels dans les 3 dernières minutes de la vidéo. Alors oui, il y a de la publicité pour EC2 derrière ce slogan (même s’il le disait déjà il y a 3 ans) et très certainement que l’architecte est, par nature, pessimiste. Mais il me semble que trop souvent nous éludons le possible échec et surtout ces conséquences. Tom DeMarco nous apprend que gérer les risques demande de les identifier, de les suivre, d'avoir des indicateurs permettant de savoir que ces derniers se concrétisent ou sont définitivement sous contrôle, et surtout de prévoir la marche à suivre dans le cas où le risque se concrétise. Gérer le risque demandera également d'investir avant même de savoir si ce dernier se concrétisera ; il faudra prévoir un plan B, envoyer des personnes en formation, prévoir et surtout tester le Plan de Continuité, peut-être à l'instar de ce que l'on peut trouver dans le Lean, développer et architecturer le produit dans des versions parallèles afin de garder le meilleur choix.
Le pendant architectural de cette gestion du risque sera alors d’architecturer nos systèmes – en collaboration étroite avec le métier - pour gérer et embrasser ces erreurs. En d’autres termes, de prévoir dans nos architectures un maximum des cas d’erreurs : - Comment gérer un mode dégradé en cas d’indisponibilité d’un système ? - Quels processus (pourquoi pas manuel) faut-il mettre en œuvre pour finaliser le processus en cas d'erreurs ou de problèmes et ne pas freiner l'utilisateur final? - Quelles informations sont nécessaires pour finir le processus ? - Quels mécanismes d’alertes met-on en place pour être pro-actif vis-à-vis du client final, l’informer de l’erreur et l’aider à finaliser son travail ? - …
Sur un système existant, il s’agira d’enrichir un existant pour s’assurer que les nouveaux cas d’erreurs sont définitivement et correctement gérés.
Alors certes, le principe de Pareto risque de nous apprendre que c'est le 20% de fonctionnalités qui plus est non visibles qui consomment 80% des délais/coûts. Mais finalement, la confiance que l'on accorde à une application n'est-elle pas plus basée sur sa capacité à gérer de manière transparente et fiable les erreurs (à sa résilience et sa robustesse) que sur n’importe quel autre critère?