Facilitating Software Architecture
1 - Centralized Architecture Practices in a Decentralized World
- La software architecture est :
- Selon Grady Booch : “the set of significant design decisions that shape the form and function of the system”.
- Selon Martin Fowler : “those decisions that are both important and hard to change”.
- Pour l’auteur, l’architecture a deux composantes bien mises en valeur par ces deux définitions : (1) le résultat final du système en lui-même d’une part, et (2) la pratique consistant à prendre les décisions d’architecture d’autre part.
- Le point (1) a été largement étayé et formalisé sous forme de patterns . Le point (2) beaucoup moins, et c’est l’objet de ce livre.
- Une bonne architecture implique :
- Des parties cohérentes, cohésives, et alignées avec le domaine.
- Des parties découplées permettant à des équipes de travailler en parallèle.
- Une architecture suffisamment qu’on peut changer facilement.
- La pratique doit donc permettre d’obtenir ce genre de résultat.
- La pratique de l’architecture sous sa forme traditionnelle ne permet pas de répondre aux enjeux d’architecture moderne.
- Il y a deux formes de pratique traditionnelle (en réalité c’est toujours un mix des deux) :
- 1 - Ivory tower architects : les architectes prennent les décisions d’architecture globales, mais aussi locales à chaque produit.
- On constate en général une homogénéisation de l’architecture pour la rendre plus intelligible et contrôlable par l’architecte, au détriment des spécificités locales de chaque produit.
- L’architecte est d’autant plus vu comme au-dessus des autres.
- 2 - Hands on architects : les architectes vont voir les équipes et co-designent et codent le système avec eux, en passant d'équipe en équipe.
- Ils n’ont pas le temps de rester assez avec chaque équipe pour répondre à toutes les problématiques, ni le temps de se consacrer suffisamment à la vision globale du système.
- 1 - Ivory tower architects : les architectes prennent les décisions d’architecture globales, mais aussi locales à chaque produit.
- Le problème principal avec les deux approches, c’est que l’architecte est responsable des décisions d’architecture à la place des équipes.
- Il n’arrive pas à suivre les détails de chaque partie locale que les équipes connaissent mieux, et il manque de temps pour traiter toutes les demandes correctement.
- Il en résulte qu’il devient un bottleneck pour les équipes, et finit par prendre des décisions de moins bonne qualité.
- Il y a deux formes de pratique traditionnelle (en réalité c’est toujours un mix des deux) :
- Selon l’auteur, le monde du logiciel a connu 5 révolutions techniques et socio-techniques :
- 1 - Agile manifesto : focus sur un code testé qui marche, livré régulièrement, et en faisant confiance aux développeurs pour faire le travail.
- 2 - Cloud computing : on a pu déployer des systèmes très rapidement, sans avoir à mettre en place une infrastructure physique pendant des semaines.
- 3 - DevOps : on a pu mettre la fonctionnalité dans les main de l’utilisateur en quelques instants, grâce au fait que les équipes de delivery avaient maintenant la main sur le déploiement et la gestion de leur application.
- 4 - Product thinking : on a cherché à obtenir du feedback des utilisateurs le plus vite et le plus souvent possible, pour s’assurer de construire la solution qui apporte le plus de valeur.
- 5 - Stream-aligned teams : on a privilégié les équipes autonomes responsables des changements de bout en bout, travaillant sur des produits sur lesquels elles ont l’ownership.
- Cette dernière a eu une période de gestation très longue :
- Elle était déjà mise en avant dans le livre Domain Driven Design d’Eric Evans et The Principles of Product Development Flow de Donald Reinertsen.
- Elle a été facilitée par le concept de microservices de James Lewis.
- Puis elle a été popularisée par Accelerate de la team DORA, Inspired de Marty Cagan et Team Topologies de Matthiew Skelton et Samuel Pais.
- Cette dernière a eu une période de gestation très longue :
- Lorsque ces révolutions sont combinées, on obtient des systèmes très efficaces, capables de mettre chaque incrément de feature dans les mains de l’utilisateur très vite, et de maximiser la valeur.
- L’approche traditionnelle de l’architecture logicielle est basée sur le contrôle, et ne permet pas d’adhérer aux 5 révolutions : il y a trop de complexité dans le système, et trop de choses qui changent pour qu’une poignée d’architectes puissent être responsables des décisions d’architecture.
- Les révolutions ont mené à une décentralisation de plus en plus grande.
- Quelques caractéristiques de ce qu’est la décentralisation :
- La décentralisation n’est pas la distribution : il s’agit d’avoir des parties autonomes plutôt qu’un tout séparé en morceaux interdépendants (par exemple monolithe distribué).
- Décentraliser veut dire abandonner le contrôle central et laisser l’indépendance aux parties.
- La décentralisation augmente la complexité. On externalise l’infrastructure, l’envoi de SMS, le paiement et d’autres choses pour pouvoir avoir plus de parties dans notre système.
- Les équipes décentralisées fonctionnent mieux.
- Les équipes ont parfois des problèmes de couplage avec d’autres équipes : en général soit du work coupling (attendre que l’autre équipe ait fini sa partie), soit du permission coupling (je dois demander avant d’agir).
- Réduire ces couplages permet d’obtenir de meilleurs résultats mais aussi des développeurs plus heureux (cf. Accelerate).
- L’idée est de laisser les équipes travailler en autonomie, en réduisant leur cycle de livraison pour qu’ils se préoccupent eux-mêmes de la valeur de ce qu’ils apportent aux clients.
- Le logiciel décentralisé fonctionne mieux. Il n’y a qu’à voir la quantité de briques qu’on externalise chez des providers payants.
- Pour que ça marche, il faut aligner les deux. Très souvent on essaye de décentraliser le logiciel alors qu’on a une structure d’équipe centralisée, et ça fonctionne mal.
- L’auteur recommande fortement l'étude célèbre de Conway de 1968 (opens in a new tab) qui ne fait que 4 pages.
- Quelques caractéristiques de ce qu’est la décentralisation :
- Les pratiques d'architecture et les architectures centralisées sont inefficaces.
- L’idée de centralisation mène souvent à celle de blocage : que ce soit un thread qui en attend un autre, une requête en DB qui attend qu’un row se libère, ou une équipe qui attend de pouvoir déployer .
- Les pratiques traditionnelles bloquent le flow de delivery. Les équipes doivent attendre les décisions des architectes, qui constituent un bottleneck.
- La raison pour laquelle ce blocage est plus gênant maintenant est que les 5 révolutions du monde du logiciel ont mené à une vitesse de changement bien plus importante qu’avant.
- Les pratiques traditionnelles ne permettent pas de récupérer suffisamment de feedback pour affecter les décisions d’architecture.
- Les architectes de type “ivory tower” ne récupèrent pas de feedback de leurs décisions et donc finissent par prendre des décisions bonnes sur le papier, mais mauvaises en pratique.
- Les architectes “hands on” one moins ce problème, puisqu’ils éprouvent dans une certaine mesure les conséquences de l’implémentation de leur propres décisions d’architecture, mais ils sont alors d’autant plus débordés.
- La nouvelle pratique doit permettre de répondre aux 3 buts de l’architecture : cohérente et cohésive, découplée, et adaptable. Pour ça, elle doit :
- Être décentralisée pour permettre aux équipes de travailler en parallèle et de réaliser de nombreuses itérations rapides.
- Mettre le feedback au cœur de son fonctionnement, que ce soit pour les architectes ou les équipes.
- Les pratiques d’architecture ne peuvent jamais protéger du chaos, c'est-à-dire des comportements complexes, imprédictibles et sensibles aux moindres changements propres aux architectures.
- L’architecture est fondamentalement incertaine, parce qu’incorporant de la variabilité à tous les niveaux.
- Il faut bien prendre l’architecture comme un tout, incluant les systèmes, mais aussi les équipes et leurs interactions, formant un système sociotechnique. Cette notion reconnaît la relation entre aspects techniques et aspects sociaux.
- Il suffit par exemple de prendre ne serait-ce qu’un bout, même simple ou peu important d’un système, et d’en augmenter la latence, pour voir apparaître une complexité qu’on n’imaginait pas.
- L’architecture a des caractéristiques fondamentalement émergentes, c’est-à-dire qu’elles sont absentes dans les parties, et apparaissent quand les parties forment un tout.
- Il existe deux types d’émergence :
- L’émergence forte concerne le fait que des parties forment un tout. Par exemple, les voitures composées de leurs parties.
- L’émergence faible n'apparaît évidente qu’après avoir dû la chercher. On peut la corriger sans difficulté, mais elle apparaîtra quand on pensera avoir pensé à tout.
- Exemple : L’auteur raconte qu’il avait mis en place un système d’assignation de tracking number dans le cadre d’un outil autour d’ebay. Ces tracking number augmentaient tous les week ends, parce qu’avec du scaling automatique, et l’augmentation de l’activité des utilisateurs le week end, des requêtes étaient en timeout. Le retry provoquait une demande de nouveau tracking number, laissant l’ancien comme réservé mais non terminé. Malgré le fait que l’équipe ait pensé à tout, ils n’avaient pas envisagé la propriété émergente entre leur système de scaling et le comportement des utilisateurs.
- Il existe deux types d’émergence :
Part I - First Principles
2 - To Practice Architecture is to Decide
- Expérience : fermez les yeux et imaginez une décision d’architecture qui est prise.
- Est-ce que c’était vous ou quelqu’un d’autre qui a pris la décision ?
- La personne qui a pris la décision était hiérarchiquement au-dessus de vous, en dessous de vous, au même niveau ?
- Quel âge avait-elle par rapport à vous ?
- Quelles compétences avait-elle par rapport aux vôtres ?
- Est-ce que c’était une personne seule ou un groupe ?
- L’architecture est fondamentalement composée de décisions.
- Les architectures évolutionnaires font que ces décisions sont nombreuses et arrivent en permanence. cf. Building Evolutionary Architectures.
- Toutes les décisions d’architecture sont des décisions techniques, mais toutes les décisions techniques ne sont pas forcément des décisions d’architecture.
- Pour définir une décision d’architecture, l’auteur met en avant la définition de Michael Nygard dans le blog post Documenting Architecture Decisions (opens in a new tab), qui dit : “'architecturally significant' decisions: those that affect the structure, non-functional characteristics, dependencies, interfaces, or construction technique”.
- Structure : si on change la structure, on change la manière dont les parties sont agencées entre-elles. Ces parties peuvent communiquer via le réseau ou via des appels de fonction.
- Exemples : comment séparer un module en plusieurs parties et quelles équipes vont être responsables de chaque partie
- Cross-functional characteristics (CFRs) : les requirements qui ne rentrent pas dans l’aspect fonctionnel tel que décrit dans une user story ou un use-case, par exemple les sujets de sécurité, de performance, de scalabilité, de réglementation, de coûts etc.
- L’auteur conseille le chapitre 6 de User Story Mapping de Jeff Patton, pour une introduction à la notion de user story.
- Il préfère cross-functional plutôt que non-functional pour éviter de définir par la négation, et aussi parce que ça représente mieux le fait que ces caractéristiques traversent le système.
- Exemples :
- Le format des logs et les outils qui vont les collecter.
- La manière dont on va scaler horizontalement notre système.
- Mauvais exemples :
- Le fait de scaler des déploiements à 3 ou 5 pods.
- Les paramètres à passer au garbage collector de notre virtual machine.
- Dependencies : il s’agit des éléments avec lesquels notre système interagit et qu’on ne contrôle pas. On doit donc faire attention à la manière dont on interagit avec ces éléments. Exemple : librairies ou services externes, plateforme qui fait tourner notre code, service fourni par une autre équipe etc.
- Mauvais exemple : quel framework de unit testing ou outils de performance testing on va utiliser (ça n’impactera pas la manière dont on conçoit le système).
- Interfaces : il s’agit des interfaces qu’on expose aux autres. On en a le contrôle, mais chaque modification à ces interfaces aura des conséquences importantes.
- Construction techniques : les techniques avec lesquelles on construit notre système affectent le système lui-même.
- Exemples :
- L’utilisation d’un outil comme LaunchDarkly pour avoir des feature toggles et mettre en prod très vite des features pour certains clients.
- L’intégration continue nécessite une grenade testabilité.
- Le TDD nécessite d’isoler la logique métier.
- Mauvais exemples :
- Quel IDE les développeurs utilisent.
- Le fait que les développeurs fassent du pair programming.
- Exemples :
- Structure : si on change la structure, on change la manière dont les parties sont agencées entre-elles. Ces parties peuvent communiquer via le réseau ou via des appels de fonction.
- On peut classer les décisions d’architecture en décisions significatives et non significatives.
- Concernant les 3 critères dependencies, interfaces et construction techniques, les changements significatifs sont en général évidents.
- Exemple :
- Une nouvelle dépendance, ou un upgrade majeur pour une dépendance existante.
- Une nouvelle API qu’on expose, ou un breaking change dans une API exposée existante.
- Une nouvelle technique de déploiement, comme le canary release, ou le blue-green deployment.
- Mauvais exemples :
- Un développeur enlève des dépendances inutilisées.
- Un architecte enlève un paramètre d’une API dont ils ont vérifié auprès des utilisateurs qu’elle n’était pas du tout utilisée.
- Un ops déploie une plateforme qui permet aux équipes de partager leurs APIs.
- Exemple :
- Concernant la structure et les cross-functional characteristics, c’est plus compliqué de définir s’ils sont significatifs.
- Concernant les changements de structure, il s’agira soit de changement d’endroit où on place une logique clé, soit du fait de commencer ou arrêter d’utiliser un design pattern.
- Exemple : des développeurs qui refactorent leur code pour extraire un micro-frontend (nouveau design pattern).
- Mauvais exemple : des développeurs refactorent leur code pour extraire une méthode privée dans une classe.
- Concernant les changements de CFRs, il faut d’abord les définir clairement avant de pouvoir savoir si elles sont significatives.
- 1 - Pour la valeur : “As a [ROLE]…I want to [ACTION]…so that [VALUE].”
- 2 - Pour le critère d’acceptance : “Given [CIRCUMSTANCES]…when [EVENT]…then [OUTCOME].”
- Exemple :
- 1 - As a customer, I want my search results within 500 milliseconds, So that I can find what I want quickly.
- 2 - Given the site is experiencing normal levels of search requests, When a customer submits a search request, Then the system responds 99% of the time with valid search results within 500 ms.
- Notre décision sera significative si elle met en danger le fait de respecter les critères d’acceptation d’un ou plusieurs autres CFRs.
- Exemple : un développeur ajoute une API Gateway publique, sans authentification, rate limiting ou autre, juste un pass-through.
- Mauvais exemple : un développeur refactore du code, enlevant un bottleneck, permettant de doubler le throughput. Aucun critère d’acceptance de CFR n’est en danger, donc ce n’est pas significatif.
- Concernant les changements de structure, il s’agira soit de changement d’endroit où on place une logique clé, soit du fait de commencer ou arrêter d’utiliser un design pattern.
- Des décisions d’architecture peuvent être significatives :
- Peu importe qu’elles aient été prises par des architectes ou développeurs.
- Peu importe qu’elles aient pris du temps ou non.
- Peu importe qu’elles aient même été délibérées ou non.
- Exemple : une développeur qui met à jour une librairie, et met à jour aussi sans faire exprès des dépendances dont une passe en licence GPL contaminante => c’est un simple développeur, qui a mis peu de temps à décider, et qui ne s’est même pas rendu compte de la décision significative qu’il avait prise.
- Les décisions ne peuvent être significatives que si elles sont liées à un système en production, ou à la partie du système qui permet de mettre le système en production (pipeline CI/CD & co). Tant que la décision n’atteint pas la production, elle ne peut pas être significative.
- Concernant les 3 critères dependencies, interfaces et construction techniques, les changements significatifs sont en général évidents.
3 - Decisions at Scale
- De manière générale, on peut décomposer le processus de décision en plusieurs étapes :
- 1 - On a besoin de prendre une décision.
- 2 - On prend la décision
- 2.a - On crée la liste des options possibles. Cette étape est particulièrement importante.
- C’est dans cette étape qu’il faut connaître un maximum de patterns d’architecture.
- C’est aussi à cette étape qu’il faut bien comprendre le problème et le contexte :
- Quelle est la situation ?
- Qu’est-ce qui a déjà été essayé ?
- Quelles sont les contraintes ? Est-ce que certaines sont en tension avec d’autres ?
- Est-ce que ne rien faire est une possibilité ?
- 2.b - On décide.
- 2.c - (facultatif) on communique sur la décision prise.
- Cette étape est souvent oubliée, résultant dans le fait que les personnes qui implémentent ne sont pas au courant, ou pas d’accord avec la décision.
- 2.a - On crée la liste des options possibles. Cette étape est particulièrement importante.
- 3 - La décision est implémentée.
- L’étape de création des options possibles peut être plus ou moins soignée ou bâclée.
- Il y a 3 manières de la faire :
- 1 - Le cas nécessitant de l’exploration : l’étape nécessite de l’effort, on ne peut pas simplement s’appuyer sur des patterns connus et évidents.
- 2 - La cas où plusieurs options connues existent : même si les options sont connues, il faut quand même de l’effort pour les expliciter et les mettre en relation les unes avec les autres.
- 3 - Le cas où on ne considère qu’une option : parfois parce que la décision n’est pas significative, parfois parce qu’on ne voit pas l’aspect significatif, ou qu’on la prend inconsciemment.
- Le fait de choisir la manière 1, 2 ou 3 dépend de la décision et de son importance, mais l’auteur remarque que bien souvent on ne consacre pas suffisamment d’importance à la phase de création des options possibles.
- C’est bien pire pour les équipes de développeurs : bien souvent, ils ne sont pas du tout exposés à cette étape, et ne voient que l’architecte qui prend la décision.
- Il y a 3 manières de la faire :
- Les décisions sont difficiles quand elles concernent un grand nombre de personnes. C’est là qu’on doit avoir des processus de décision solides.
- Les deux critères importants pour l’auteur sont :
- 1 - Est-ce que le pouvoir d’initier la décision est centralisé ou décentralisé ?
- 2 - Quelle est la vitesse à laquelle la procédure permet de définir des options et prendre des décisions ?
- L’auteur en distingue 6 (elle sont aussi décrites sur thedecider.app (opens in a new tab)) :
- Les procédures centralisées : une seule personne a le pouvoir de décision, et peut l’utiliser de différentes manières.
- 1 - Autocratic decision process : une seule personne crée la liste des options et prend la décision. Les autres ne font qu’implémenter.
- La prise de décision peut être très rapide, mais la personne peut aussi se retrouver à être un bottleneck si les décisions à prendre s’empilent.
- Exemple : un chief architect rejoint une entreprise et prend la décision de passer d’AWS à Azure sans avoir consulté personne.
- 2 - Delegation decision process : la personne qui a le pouvoir délègue la décision à une personne, qui va donc lister les options et prendre la décision.
- Ça ressemble beaucoup à l’autocratic decision process, à la différence que la décision peut être plus pertinente si on délègue aux personnes les mieux placées.
- Exemple : le chief architect rejoint l’entreprise, mais ne connaît pas suffisamment AWS et donc délègue la décision au lead infrastructure architect.
- 3 - Consultative decision process : la personne qui a le pouvoir consulte d’abord les personnes de son choix, avant de faire la liste des options et prendre la décision.
- Ça peut être un peu plus lent que les deux précédentes méthodes, mais on recueille plus de points de vue. Par contre, vu que la personne choisit de consulter qui elle veut, on peut se retrouver avec des experts du sujet qui ne sont pas du tout consultés.
- Exemple : le chief architect consulte le lead infrastructure, et quelques autres personnes, avant de lister les options et prendre la décision.
- 1 - Autocratic decision process : une seule personne crée la liste des options et prend la décision. Les autres ne font qu’implémenter.
- Les décisions décentralisées : le pouvoir de décision est distribué.
- 4 - Consent decision process : C’est toujours la même personne qui liste les options et prend la décision, mais un groupe large de personnes peuvent bloquer la décision en mettant un véto. S’il y a véto, la personne doit soit faire un autre choix, soit changer la liste des choix possibles.
- Les personnes non-décisionnaires peuvent parfois abuser du véto, en le mettant jusqu’à ce que la décision soit celle qu’elles veulent. Donc la décision risque d’être lente.
- Exemple : le chief architect propose de coder les nouveaux microservices en Java 8 parce que c’est ce qu’il connaît. Sa décision est bloquée par un véto d’une ou plusieurs personnes.
- 5 - Democratic decision process : une personne crée la liste des options, mais ensuite le groupe entier vote pour l’option qu’il préfère.
- La décision va vite, mais le risque c’est que la minorité qui perd se retrouve désengagée parce qu’elle pense qu’elle a de bonnes raisons d’être pour une autre option, même si elle est minoritaire.
- Exemple : le chief architect propose la liste “Java 8, Cobol, Lisp, Rust”, et le groupe choisit. Il reste quand même la question de savoir qui va avoir un droit de vote : juste les tech leads ? l’ensemble des développeurs ? etc.
- 6 - Consensus decision process : l’ensemble du groupe participe à l’étape de création des options, et aussi à l’étape de la prise de décision, où on s’assure que tout le monde consent avant de décider.
- On a une bien plus grande implication de chacun, mais la décision risque de prendre beaucoup de temps. Un autre problème peut être le fait d’aller systématiquement vers le choix du plus petit dénominateur commun de compromis : ce n’est pas toujours une bonne chose pour une architecture.
- Exemple : le chief architect lance le sujet, et les développeurs arrivent à une liste “Kotlin, C#, TypeScript, Rust”, puis discutent jusqu'à arriver à un accord sur un langage.
- 4 - Consent decision process : C’est toujours la même personne qui liste les options et prend la décision, mais un groupe large de personnes peuvent bloquer la décision en mettant un véto. S’il y a véto, la personne doit soit faire un autre choix, soit changer la liste des choix possibles.
- Les procédures centralisées : une seule personne a le pouvoir de décision, et peut l’utiliser de différentes manières.
- Quand on classe les procédures selon les deux axes (décentralisation et vitesse de prise de décision), on voit qu’on a soit des procédures décentralisées, soit des procédures rapides.
- On pourrait imaginer le cas “centralisé et lent” avec un autocrate hésitant qui décide seul mais met beaucoup de temps à décider, mais ça n’a aucun intérêt pour nous.
- L’autre case est par contre beaucoup plus intéressante : est-ce qu’on peut avoir une procédure qui soit à la fois rapide et décentralisée ?
- Si on examine les procédures listées :
- Sur l’aspect rapidité, plus la personne qui décide est autonome dans la décision, et plus la décision est rapide. Consulter les autres prend peu de temps, mais s’ils ont une voix dans la décision elle-même, ça va la ralentir.
- Sur l’aspect décentralisation, ce qui compte c’est le nombre de personnes qui peuvent participer à la décision, mais aussi le nombre de personnes qui peuvent l’initier.
- Et donc, une procédure qui serait à la fois rapide et décentralisée devrait :
- 1 - Impliquer les bonnes personnes.
- 2 - Laisser un grand nombre de personnes initier une décision et décider.
- 3 - Mettre en avant la confiance pour que chacun s’implique dans les décisions où il a quelque chose à apporter.
- 4 - Minimiser le besoin de communiquer la décision.
- Si on examine les procédures listées :
- Les deux critères importants pour l’auteur sont :
4 - The Architecture Advice Process
- En tant qu’architecte traditionnel, l’auteur a été principalement confronté à 3 problèmes (que ce soit en mode hands on ou ivory tower) :
- 1 - Étant donné sa responsabilité sur les décisions, il était sur le chemin critique des équipes, et donc finissait par les bloquer d’une manière ou d’une autre.
- 2 - Il ne pouvait pas être au courant des détails et nuances de l’ensemble des systèmes en place, et finissait par faire des erreurs à cause de ça.
- 3 - Il n’arrivait pas à communiquer efficacement ses décisions, et donc pouvait ne pas les voir implémentées correctement.
- La notion d’advice process vient initialement du livre The Decision Maker de Dennis Bakke, puis a été popularisé par Reinventing Organizations de Frédéric Laloux.
- L**’architecture advice process** peut être décrit comme suit : n’importe qui (membre d’une équipe ou personne avec un rôle cross-team) peut prendre une décision (choisir une des options), à condition d’avoir consulté les personnes suivantes durant la phase de création des options :
- 1 - Des personnes affectées par la décision
- 2 - Des personnes qui ont une expertise dans le domaine dans lequel la décision est prise.
- L’advice process peut être vu comme un contrat social : on a confiance dans le fait que les autres, quand ils prendront des décisions, écouteront les perspectives des bonnes personnes. Et on promet nous-mêmes de faire de même.
- Cette confiance s’établit entre celui qui décide (une personne, ou une équipe représentée par un membre de l’équipe), et ceux qui subissent la décision, avec dans l’idée que les rôles vont s’inverser régulièrement.
- L’advice process est à la fois rapide et décentralisé.
- Il est rapide :
- Le nombre de personnes qui participent à l’étape de prise de décision est de 1. Le nombre de personnes qui peuvent mettre un véto est de 0.
- Il se retrouve légèrement plus rapide que le consultative process parce que la décision va être prise par ceux qui en ont le besoin direct, et donc ils seront pressés de la prendre pour avancer.
- Concernant les personnes consultées :
- Les équipes vont naturellement chercher à minimiser leur nombre, ce qui va les forcer à construire des systèmes bien délimités.
- Le rapport aux experts est aussi différent : puisqu’il n’y a plus besoin de les convaincre, on est purement sur du partage de connaissances.
- Puisque les personnes concernées sont déjà mises au courant du sujet au moment de la consultation, il n’y a plus besoin de faire de grands efforts pour la phase de partage de la décision.
- Il est décentralisé. Si on reprend la définition qu’on se donne de décentralisé : plus il y a de personnes qui peuvent initier et participer aux décisions, plus la procédure est décentralisée.
- Il offre une décentralisation maximale sur la question de qui peut prendre une décision : n’importe qui qui en ressent le besoin.
- En revanche, il est moins décentralisé que le consensus process parce qu’il n’implique pas tout le monde tout le temps.
- Il gagne donc sur la rapidité, mais aussi sur la responsabilisation, puisqu’il y a une personne qui porte la décision, là où avec le consensus process la responsabilité diluée entre tous.
- Il est rapide :
- Story 1 : une équipe de développeurs décide d’utiliser les release toggles.
- On a une équipe dont le PM pousse à livrer les features par des incréments de plus en plus petits dans les mains du client, et certains membres ayant lu Accelerate, veulent expérimenter le trunk based development.
- L’équipe constate qu’il lui faut une manière de cacher les fonctionnalités non terminées : une forme de release toggles.
- Connaissant bien les tenants et aboutissants de son système, de son contexte, ses compétences etc. l’équipe réfléchit et tombe sur une première solution : implémenter des checks booléens dans le code pour cacher les features non terminées.
- Ils décident alors d’aller demander des conseils, d’abord aux autres équipes qui pourraient être affectées par cette décision. Pour les trouver ils se sont posé des questions du genre : quelles équipes devront faire du travail supplémentaire du fait de notre décision ?
- Le retour principal des équipes concernées est une inquiétude sur leur capacité à tester contre un service qui leur est caché, mais qu’ils auraient besoin de de pouvoir requêter.
- L’équipe initiale n’a pas pu y penser parce qu’il n’est pas si facile que ça de se mettre à la place des autres pour prendre leur perspective. C’est pour ça qu’on leur demande directement.
- Ils décident ensuite de demander des conseils aux personnes ayant une expertise sur le sujet. Il s’agit de personnes qui ont de l’expérience sur le sujet, ou une vision plus large du système ou dans le temps.
- Ils vont en parler à Fiona la systems architect, à JB le lead QA, et à Monira, une autre PM dont ils savent qu’elle a eu une expérience avec les release toggles.
- Fiona un article sur les feature toggles, et leur parle de sa propre expérience, et mentionne notamment le fait qu’il faut que chaque feature toggle soit conçue comme temporaire, avec des mécanismes qui rappelleront de l’enlever pour éviter qu’elle traîne. Elle leur conseille aussi d’en parler avec Yinka, le lead infrastructure pour les histoires d’environnements, de permissions.
- JB leur parle de la testabilité qui devient un peu plus lourde : par exemple il faut bien penser à tester les features avec le toggle désactivé, et activé.
- Yinka leur conseille de plutôt passer par des variables d’environnement pour éviter de devoir repasser par la CI et redéployer tout le code juste pour activer/désactiver des toggles.
- Monira leur dit qu’elle est plutôt d’accord avec les conseils précédents, et ajoute que les variables d’environnement pourraient permettre de faire des démos rapides à un PM ou à un client, sans prendre trop de temps à l’équipe.
- L’équipe décide de suivre le conseil de Yinka pour utiliser les environment variables (qui va aussi arranger les équipes affectées pour leurs tests qui seront plus faciles), et celui de Fiona de tracker les feature toggles, qu’ils choisissent de faire dans Jira pour donner de la visibilité aussi à leur PM (conseil de Monira).
- Finalement ils reviennent vers les différentes parties prenantes pour leur annoncer leur décision : c’est plutôt facile puisque ces personnes ont globalement déjà en tête le contexte.
- Dans cet exemple, le décision taker et l’option maker est le même : l’équipe qui a ressenti le besoin de ce changement d’architecture.
- Cette expérience a non seulement permis d’avoir une solution meilleure que si l’équipe avait décidé sans advice process, mais aussi a permis à l’équipe :
- D’en apprendre beaucoup sur le sujet des feature toggles.
- De mieux comprendre le point de vue des personnes avec des rôles spécifiques (architecte, QA, spécialiste infra etc.).
- De tisser un réseau au sein de l’entreprise, qu’elle renforcera d’autant plus à chaque fois qu’elle aura des décisions à prendre en advice process.
- On a une équipe dont le PM pousse à livrer les features par des incréments de plus en plus petits dans les mains du client, et certains membres ayant lu Accelerate, veulent expérimenter le trunk based development.
- Story 2 : un architecte décide de démêler un problème de workflow.
- La majorité des décisions d’architecture se traitent plutôt comme la Story 1, mais certaines décisions portent sur une problématique qui impacte un système comprenant plusieurs équipes. Les personnes les mieux placées pour repérer et traiter ce genre de problématiques sont les personnes qui ont un rôle plus large, comme les architectes.
- Dans le cadre d’un produit mature, il y a un microservice qui devient petit à petit un bottleneck de delivery et de performance.
- Initialement, il servait à externaliser la logique de workflow du parcours utilisateur d’une équipe pour pouvoir y faire des changements sans mettre à jour l’app mobile. Puis comme il fonctionnait bien, d’autres équipes y ont ajouté leur logique, et ainsi de suite.
- Depuis quelque temps, les architectes ont repéré que ce microservice était l’objet de nombreux problèmes. A la fois des bugs difficiles à reproduire, et aussi du work coupling : certaines équipes attendent que l’équipe owner du microservice de workflow fasse des modifications pour eux.
- Un architecte système décide de sonder les équipes concernées utilisant le service de workflow pour comprendre ce qu’il fait, et quels sont les besoins de ces équipes.
- Il remarque que le code est plutôt de bonne qualité, bien testé etc. mais que le microservice fait beaucoup de choses, principalement 3 patterns :
- 1 - En tant que service de workflow, dirigeant les utilisateurs vers des étapes dont le code était ailleurs.
- 2 - Le code de certaines étapes devenait dupliqué entre Swift et Kotlin, et donc ces équipes ont décidé de le migrer vers le service de workflow commun, tout en respectant le fait qu’il reste stateless, c’est-à-dire qu’on lui passe l’état et qu’il ne persiste rien. Ils l’ont fait pour éviter la duplication, ce qui est louable.
- 3 - Certaines équipes avaient construit un système de persistance par dessus le service de workflow pour le rendre indirectement stateful. Ils l’ont fait essentiellement pour des raisons de performance.
- Il remarque que le code est plutôt de bonne qualité, bien testé etc. mais que le microservice fait beaucoup de choses, principalement 3 patterns :
- Il va ensuite parler aux personnes expertes de ce sujet.
- D’abord à Cassie, qui est experte mobile. Elle lui dit que ce genre de problème est régulier dans le monde mobile étant donné la nature des déploiements. Elle conseille :
- De prendre en compte l’ensemble des besoins des équipes.
- De les adresser individuellement.
- De laisser certains problèmes de côté, en demandant aux équipes de simplifier leur implémentation et chercher une solution tierce ou open source de remplacement.
- Ensuite il parle à Patricia, dev mobile senior récemment embauchée, et venant d’une entreprise qui avait notoirement le même genre de problèmes. Elle raconte les solutions qu’ils avaient mis en place et discute des avantages et inconvénients de certains outils, notamment Kotlin Multiplatform qui permet de mettre en commun du code Android & IOS.
- Enfin, il parle à des personnes connaissant des systèmes de workflow similaires : Gayathri, un ancien dev qui se souvient de l’enterprise service bus qui existait autrefois, et Isha, un QA qui a travaillé sur un système de workflow à base d’Apache Camel. Les deux donnent des pistes.
- D’abord à Cassie, qui est experte mobile. Elle lui dit que ce genre de problème est régulier dans le monde mobile étant donné la nature des déploiements. Elle conseille :
- L’architecte va alors prendre sa décision :
- 1 - Des refactorings pour encourager les utilisations stateless et rendre plus difficiles les autres utilisations, et le fait d’adopter un fonctionnement inner source pour le microservice, c’est-à-dire comme de l’open source mais en interne.
- 2 - Identifier un élément de logique partagé entre Android et IOS, et qui s’est retrouvé dans le service de workflow, et le réimplémenter en Kotlin Multiplatform pour le garder côté code mobile plutôt que dans le backend.
- 3 - Refactorer les utilisations stateful pour les rendre stateless. Chercher des solutions pour régler les problèmes de performance, notamment autour de real time databases for mobile, et backends for frontends.
- Avant de prendre sa décision, l’architecte invite l’ensemble des équipes concernées et leur présente un draft de la décision, pour prendre des feedbacks, notamment sur la manière d’implémenter les choses.
- Et finalement l’implémentation se fait petit à petit par les équipes concernées qui ont bien compris l’intérêt du changement.
- Cette story montre que même pour les décisions avec un large impact, les personnes qui les prennent doivent au minimum écouter les parties prenantes et s’appuyer sur elles.
- Pour l’auteur, les notions d’opinion et d’advice sont des near ennemies.
- near ennemies veut dire que l’un est en quelque sorte la contrefaçon de l’autre. Par exemple :
- Une équipe DevOps est un near ennemy du mindset DevOps : avoir une équipe distincte est contraire à l’idée fondamentale du DevOps qui est de casser le silo entre Dev et Ops.
- Une transformation agile imposée par le haut est un near ennemy des équipes agiles : le manifeste parle de laisser les équipes s’auto-organiser en les soutenant, ce qui est le contraire d’imposer une transformation.
- L’auteur a fait une présentation d’une liste de near ennemies du DDD (opens in a new tab).
- L’opinion donne une direction mais c’est tout, là où l’advice va donner la direction, mais aussi expliquer les raisons sous-jacentes de pourquoi cette direction, et l’étayer avec des faits, de l’expérience.
- Exemple d’advice : I would use this build because not only does it have licensing terms appropriate to our company’s standards but also because their releases always keep up with the upstream OpenJDK from Oracle, and they have a great wiki as well as an active community who responded rapidly to us when we asked them for help on a weird issue we had.
- Exemple d’opinion : I would use this OpenJDK build because it works better. It’s faster, cheaper, and higher quality.
- Quand on a une opinion en face de nous, on peut tenter d’en tirer un advice en posant des questions du type “Pourquoi ?”, “Comment ?”.
- L’architecture consiste souvent en un it depends on, et l’advice donne justement la suite du “on”.
- Certains architectes qui avaient l’habitude de tout décider, risquent dans un premier temps (consciemment ou non) de donner plus souvent des opinions que des advices.
- C’est une dynamique qui ne devraient pas durer parce que le fait que la personne qui pose la question est celle qui sera accountable, fait qu’à la fois elle a tout intérêt à aller chercher les advices, et à la fois les autres ont tout intérêt à les donner pour que la décision soit la bonne.
- near ennemies veut dire que l’un est en quelque sorte la contrefaçon de l’autre. Par exemple :
- L’advice process se base sur les conversations, et notamment que les conversations qui sont nécessaires aient lieu.
- Le fait de se concentrer sur les conversations dans le cadre de décisions décentralisées fait qu’on se rapproche de la notion d'anarchie.
- Pour que ça fonctionne, il faut que chaque partie se fasse confiance. Même si dans les systèmes traditionnels on constate généralement une confiance diminue dès qu’on dépasse le cercle de l’équipe, selon l’auteur, l’advice process permet de maintenir une confiance à plus large échelle.
5 - Rolling Out the Architecture Advice Process
- Pour mettre en place l’advice process, la procédure dépend des pouvoirs de prise de décision qu’on a :
- Si on a déjà des pouvoirs de prise de décision (par exemple si on est architecte), on peut directement appliquer l’advice process soi-même. A chaque fois qu’il faut prendre une décision, on interroge les personnes concernées et expertes, en leur disant bien qu’on le fait dans le cadre d’un advice process. Ensuite on prend la décision, et on retourne voir les parties prenantes pour la leur communiquer.
- Si on manque de pouvoir de prise de décision (par exemple membre d’une équipe de développement), on peut quand même commencer à appliquer l’advice process, en indiquant bien à toutes les parties prenantes ce qu’on fait. La différence c’est qu’on prend une pseudo-décision, qu’on donne au vrai décisionnaire à la fin. Le but est de le convaincre que notre équipe est capable de prendre de bonnes décisions de cette manière.
- Si on a la capacité à décider de la manière dont on décide (CTO ou assimilé), on peut mettre en place une expérimentation à petite échelle : on prend quelques équipes (pas plus de 3) volontaires et un architecte, et on leur explique l’advice process à expérimenter pendant 3 mois. Une fois que c’est fait, on fait une rétrospective, et on voit ce qu’il faut corriger, et si on peut étendre à plus d’équipes.
- L’auteur identifie 4 problèmes principaux qu’on rencontre en mettant en place l’advice process :
- 1 - Une mauvaise compréhension de l’advice process.
- Il faut expliquer dès le départ l’advice process aux personnes qui participent à l’expérimentation, par exemple avec une présentation suivie de questions.
- Il faut insister sur les points principaux, notamment les étapes de la procédure, les rôles des personnes, et le shift d’accountability.
- 2 - Les bonnes personnes ne sont pas consultées pour donner l’advice
- Ce problème concerne en général les développeurs qui ne savent pas vraiment à qui parler, plutôt que les architectes qui ont déjà l’habitude d’aller consulter les bonnes personnes.
- La première chose à faire pour les équipes de développeurs est de demander un advice à l’architecte, notamment pour lui demander ensuite qui d’autre serait pertinent pour donner un advice sur ce sujet.
- Une bonne pratique est de construire petit à petit une liste indiquant les personnes compétentes sur des sujets spécifiques. Par exemple pour “information security”, pour “personally identifiable information”, pour “user onboarding flow” etc.
- Parfois la liste de personnes à consulter est énorme : c’est pas grave, il faut les consulter quand même. Ça peut pousser à diviser la grande décision en plus petites, ou reconsidérer l’intérêt de prendre une décision sur ce sujet.
- 3 - On oublie de demander “Pourquoi ?” lors de l’advice et on passe à côté d’informations essentielles.
- Attention aux supérieurs hiérarchiques à qui on demande un advice : ils risquent de se cantonner à l’opinion, ou à une direction à suivre. Il faut alors leur demander le pourquoi de leur opinion, et leur rappeler que c’est nous qui sommes accountable.
- Il faut aussi chercher des advice auprès des personnes avec des points de vues différents du nôtre. Ca ne pourra qu’enrichir notre perspective, et rendre notre décision plus solide.
- 4 - Un manque de clarté sur le shift d’accountability.
- Généralement la crainte qui vient en tête des personnes à qui on parle d’advice process c’est qu’une personne prenne une décision qui ne l’arrange qu’elle, contre tous les advices. Ça révèle que le shift d’accountability n’a pas clairement été compris.
- Le décideur a l’accountability de la décision (il en subira les conséquences), et donc il a tout intérêt à aller chercher les advices et bien les comprendre pour prendre la meilleure décision possible.
- On peut imaginer 3 cas où la personne va contre l’ensemble des advices :
- 1 - Un manque de compréhension du décideur : dans ce cas l’advice process l’aide puisqu’il est poussé à aller chercher les advices.
- 2 - Un insight unique que seule le décideur a : dans ce cas l’advice process lui permet de le communiquer à ceux à qui il va parler.
- 3 - De mauvaises intentions : l’auteur n’a jamais vu ce cas, mais si ça arrive il s’agit d’un problème de management, et en dernier ressort la personne n’est peut être pas à sa place dans l’organisation.
- Dans le cas où une personne n’est pas prête à assumer l’accountability d’une décision, elle peut toujours proposer à quelqu’un d’autre s’il est prêt à porter la décision. La personne initiale pourra peut être apprendre en voyant l’autre faire, et porter une autre décision la prochaine fois.
- Généralement la crainte qui vient en tête des personnes à qui on parle d’advice process c’est qu’une personne prenne une décision qui ne l’arrange qu’elle, contre tous les advices. Ça révèle que le shift d’accountability n’a pas clairement été compris.
- 1 - Une mauvaise compréhension de l’advice process.
- Les personnes exposées à l’idée d’advice process ont souvent un manque de confiance lié à plusieurs points :
- Manque de confiance dans sa capacité à décider, ou la capacité à décider des autres.
- C’est normal, les personnes qui n’ont pas l’habitude de prendre des décisions d’architecture vont devoir l’apprendre. C’est une compétence qui s’améliore par la pratique.
- Un élément qui peut aider est un endroit où chacun recevrait de l’aide pour pratiquer l’advice process, en voyant les autres respecter les étapes, et en le faisant soi-même.
- Manque de confiance sur les advices réellement demandés et donnés.
- Pour aider à construire sur ce point, on peut mettre en place un mécanisme de transparence qui liste les advices donnés et les personnes consultées.
- Manque de confiance lié au fait de ne pas savoir tout ce qui se passe.
- Il n’y a pas de centre de la décision, et donc on ne peut parler à personne qui ne sache tout ce qui est en cours d’un point de vue architecture.
- Malgré tout, il serait bon de pouvoir facilement trouver tout ce qu’il faut à propos d’une décision donnée.
- Ces trois manques de confiance peuvent être mitigés par la mise en place des ADRs.
- Manque de confiance dans sa capacité à décider, ou la capacité à décider des autres.
6 - Architectural Decision Records
- L’auteur considère l’ADR comme outil minimal pour accompagner l’introduction de l’architecture advice process.
- L’ADR va cadrer l’ensemble des 3 étapes du processus de décision : option making, decision taking et decision sharing.
- Historiquement, l’ADR :
- Date de 2005 dans un papier de Jeff Tyree.
- A été popularisé par un blog post (opens in a new tab) de Michael Nygard.
- Est détaillé sur un site de référence (opens in a new tab).
- A un chapitre consacré dans Fundamentals of Software Architecture.
- Les ADRs ont en général un contenu texte d’environ 2 pages, et sont immutables, c’est-à-dire que si on veut changer une décision, il faut refaire un ADR.
- Ils sont écrits de manière à en faciliter la lecture, au détriment de l’écriture.
- Un ADR complet est structuré de cette manière :
- Le titre doit être suffisamment descriptif pour comprendre la décision sans ouvrir l’ADR. Il doit donc être changé une fois la décision prise pour inclure la décision.
- Exemple : ADR002—Shorten Inventory IDs with Nano ID
- Les metadata :
- L’identifiant permet de se référer à l’ADR sans aucune ambiguïté.
- Le statut permet de savoir où en est l’ADR.
- La date permet de savoir quand est-ce que le statut a évolué pour la dernière fois (sachant qu’une fois Accepted, il ne peut plus changer).
- L’auteur est la personne (ou l’équipe si une équipe entière s’en charge) qui est responsable de prendre la décision.
- La décision indique l’option choisie, et la décrit brièvement. Elle n’indique pas le contexte, les avantages et inconvénients ou les autres options possibles.
- Le contexte permet de savoir pourquoi la décision est importante, et les aspects principaux qu’avait l’auteur en tête au moment de l’ADR.
- Il est en dessous de la décision parce que pour le lecteur la décision est plus importante à connaître immédiatement.
- Les options représentent les possibilités considérées.
- On met en premier celle qui est sélectionnée par le décideur pour faciliter la vie des lecteurs.
- Les options sont juste listées pour pouvoir les avoir sous les yeux toutes en même temps, les conséquences sont détaillées en dessous. On peut aussi faire la version où les conséquences sont détaillées pour chaque option, mais l’auteur préfère les séparer pour aider le lecteur de l’ADR.
- Exemple :
-
- (SELECTED) A4VHAOFG: Random generated letters and numbers with Nano ID
-
- 123456: Automatically generated sequence ID
-
- Canvas: Manually generated ID
-
- Les conséquences indiquent pourquoi chaque option a été choisie ou rejetée.
- Pour l’option sélectionnée, on va laisser les avantages “Selected because…” et les inconvénients “Selected despite…”.
- Pour les autres options, on peut se restreindre aux désavantages pour lesquels on ne les a pas sélectionnés. Parfois, on peut vouloir mettre aussi les avantages.
- Les advices contiennent chaque advice récolté par le décideur, avec le nom de la personne qui a donné l’advice, et la date de l’advice.
- Cette section est un ajout à la structure habituelle des ADRs, pour qu’ils servent de socle à l’advice process.
- Le titre doit être suffisamment descriptif pour comprendre la décision sans ouvrir l’ADR. Il doit donc être changé une fois la décision prise pour inclure la décision.
- L’ADR sert aussi de support pour aider dans le processus de décision :
- Étape 1 : on crée l’ADR vide, et on remplit les metadata.
- Un template fait par l’auteur est dispo ici (opens in a new tab).
- Le titre n’a pas beaucoup d’importance à ce stade, il sera de toute façon changé très bientôt.
- Étape 2 : on remplit le contexte.
- On cherche les choses à mettre après le “on” de “it depends on”. Le but est de comprendre l’espace du problème.
- Pour l’auteur, les sections Contexte et Consequences sont les deux plus importantes pour aider à la prise de décision.
- On écrit ce qui nous passe par la tête, puis on met en forme en ayant en tête les potentiels advisers comme cible.
- D’ailleurs si des advisers nous viennent en tête, il faut noter leur noms pour ne pas oublier de leur parler.
- On peut aussi ajouter un schéma pour expliciter le contexte, sans passer trop de temps dessus à ce stade.
- Étape 3 : on liste les options et leurs conséquences.
- On commence par la partie conséquences : on écrit les conséquences pour les options qu’on a déjà en tête, sans oublier d’envisager l’option “ne rien faire”. Le but est de d’éclairer les raisons d’envisager chacune des options dans notre contexte.
- Idéalement il faudrait se retrouver avec 3 à 5 options, 2 étant un minimum.
- On continue à raffiner les conséquences de nos options tout au long du processus de décision. On peut aussi ajouter des schémas pour les représenter plus clairement.
- Étape 4 (optionnel) : pré-sélectionner une option
- Si on pense qu’une des options est préférable à ce stade, on peut la pré-sélectionner, et changer le statut de l’ADR de “Draft” à “Proposed”.
- Cette étape est optionnelle.
- Pré-sélectionner une option avant d’aller demander des advices a l’avantage de leur indiquer dans quelle direction on s'apprête à aller, pour qu’ils concentrent plus d’attention à éventuellement critiquer cette option.
- Mais ça peut aussi avoir l’inconvénient de les influencer, en particulier si on a une position d’autorité.
- La suite est d’aller voir les personnes qui vont donner des advices.
- Étape 1 : on crée l’ADR vide, et on remplit les metadata.
- Étape 5 : on va chercher les advices, et on met à jour l’ADR.
- Conseils généraux :
- On peut solliciter des advices tôt dans le processus de décision, dès qu’on a un début de draft de la section Contexte. Dans ce cas, on demande de l’aide pour construire le contexte et les options.
- C’est ce qu’avait fait l’architecte dans la Story 2 : il était allé voir les équipes concernées pour voir l’usage de chacune du module de workflow.
- On peut solliciter des advices tardivement, une fois qu’on a affiné nos options et conséquences, et qu’on en a pré-sélectionné une.
- C’est ce qu’avait fait l’équipe dans la Story 1 : ils avaient pré-sélectionné l’option des toggles dans le code, avant d’aller voir les autres équipes qui leur ont dit qu’en fait ça avait un impact sur eux.
- Les advices doivent porter sur l’ensemble des parties de la décision.
- Il faut bien le préciser explicitement aux personnes à qui on demande des advices, en particulier si on leur demande tardivement sur un ADR déjà bien rempli.
- Les advices peuvent :
- Ajouter des options.
- Améliorer la section Context.
- Donner des insights supplémentaires sur les conséquences positives et négatives des options.
- Amener à scinder la décision en plusieurs décisions.
- Si nécessaire, on peut retourner voir une personne qui nous a déjà donné un advice pour creuser quelque chose qu’on n’avait pas en tête à ce moment-là.
- On peut solliciter des advices tôt dans le processus de décision, dès qu’on a un début de draft de la section Contexte. Dans ce cas, on demande de l’aide pour construire le contexte et les options.
- Avant d’aller chercher les advices, on établit une liste de personnes qu’on pense être celles impactées par la décision, et celles qui sont expertes du domaine. On met cette liste dans la section Advices de l’ADR.
- On peut ensuite mettre en place des meetings avec chaque personne.
- Avant le meeting, on lui met à disposition l’ADR tel qu’il est actuellement, pour que la conversation puisse être plus efficace.
- Pendant le meeting, on prend des notes sur les advices que la personne donne, dans la section Advices de l’ADR.
- Après le meeting, on met en forme les notes, et on demande à la personne de les relire après coup, pour être sûr qu’il s’agit bien de son advice clair et complet, et d’ajouter ce qu’il faut sinon.
- A chaque fois qu’on a fait un meeting avec une personne, on repasse sur l’ADR pour mettre le mettre à jour si nécessaire au regard des advices données.
- On ajoute les éléments supplémentaires, comme par exemple des options nouvelles, même si on est en désaccord avec celles-ci, ou des avantages ou inconvénients supplémentaires pour certaines options.
- On peut clarifier certaines parties si elles avaient été mal comprises par la personne donnant l’advice.
- On peut indiquer dans le texte de l’ADR quand il y a des advices qui vont à l’encontre de notre avis et qu’on choisit de ne pas suivre.
- TODO : technique montrée plus tard ?
- Conseils généraux :
- Étape 6 : on prend la décision, et on complète l’ADR.
- On met à jour les options et les conséquences en fonction de l’option choisie :
- On rédige la section Options qui liste les options, avec l’option sélectionnée en 1er.
- On déplace les conséquences de l’option sélectionnée en haut de la section Consequences, en l’indiquant comme sélectionnée.
- On reformule les upsides et downsides pour l’option sélectionnée en “Selected because…” et “Selected despite…”, et pareil pour les options non sélectionnées “Rejected because…” et “Rejected despite…”.
- On remplit la section Decision, et on change le titre pour refléter l’option choisie.
- On change le statut à “Accepted” et on met à jour la date.
- On met à jour les options et les conséquences en fonction de l’option choisie :
- Étape 7 : on partage la décision, en partageant l’ADR avec tous ceux qui sont concernés ou qui ont contribué.
- Concernant les statuts des ADRs :
- Il y a les statuts classiques : Draft, Proposed, Accepted, Superseded.
- Superseded est utile quand une décision est en partie invalidée par une décision ultérieure.
- On peut aussi ajouter des statuts non standards qui peuvent parfois être utiles :
- Expired : pour faire un ADR explicitement timeboxé, et qu’il faut revisiter à un certain moment parce qu’il expire.
- Retired : dans le cas où un produit est retiré de la circulation, l’ADR le concernant peut être considéré comme retiré de la circulation aussi.
- Rejected : pour l’auteur n’est pas utile. Soit c’est Accepted avec la décision de ne rien faire, soit Superseded par un autre ADR si on change la décision.
- Il y a les statuts classiques : Draft, Proposed, Accepted, Superseded.
- Les ADRs doivent être dans un même endroit (d’où l’intérêt d’un ID unique).
- Il vaut mieux éviter les outils spécifiques aux architectes pour faire en sorte que l’ensemble des développeurs l’utilisent aussi.
- Une des solutions est le wiki (ou assimilé) qui contient déjà la documentation des produits existants.
- Une autre possibilité est d’utiliser le gestionnaire de version, créer une pull request par ADR (qu’on merge quand le statut est Accepted), et rédiger l’ADR dans un fichier markdown.
- Enfin, la solution préférée de l’auteur est d’utiliser un outil de ticketing. Ça a l’avantage de pouvoir mettre en avant certains champs (Auteur, Statut, Date), être alerté par exemple quand le statut d’un ADR change, ou encore pouvoir afficher les ADRs selon des critères particuliers (recherche par auteur, par date etc.).
- Les ADRs doivent raconter l'histoire du système. Il faut donc qu’une personne avec un rôle cross-équipe s’occupe de :
- S’assurer régulièrement que les ADRs ont un identifiant unique et un titre clair.
- Créer et maintenir une page de changelog qui montre les ADRs acceptés en partant du plus récent.
- Créer et maintenir une page donnant un résumé ou une liste des ADRs les plus importants.
- La page peut être enrichie avec des diagrammes, des liens vers des endroits importants de la codebase, ou une domain-driven design vision (cf. chapitre 15 de Domain-Driven Design d’Eric Evans).
- Les ADRs les plus importants sont notamment ceux qui ont l’impact le plus large, mais également par exemple des ADRs avec un impact large et où il a été choisi de ne rien faire.
Part II - Nurturing and Evolving Your Culture of Decentralized Trust
7 - Replacing Hierarchy with Decentralized Trust
- Les frameworks “enterprise” d’architecture comme The Open Group Architecture Framework (TOGAF) ou Open Agile Architecture (O-AA) sont compatibles avec l’advice process, notamment parce qu’ils ont dû s'adapter aux 5 révolutions, et acceptent le shift de responsabilité et d’accountability.
- L’accountability revient au décideur : soit l’architecte pour les décisions cross-équipes, soit l’équipe entière (ou le team lead si l’équipe choisit de faire comme ça) pour les décisions où une équipe est principalement concernée.
- Personne n’est obligé de décider, mais ceux qui le font doivent utiliser l’advice process en toute transparence, et ceux qui veulent se lancer sont encouragés.
- Pour que l’advice process marche et que la confiance s’installe et perdure, il faut trouver juste assez d'accords formels (contrat social, ADR), et juste assez de pratiques standard (tout ce qui vient dans les quelques chapitres suivants).
- A partir du moment où on met en place l’advice process, la culture d’entreprise va venir combler l’écart avec les structures en place, et potentiellement menacer la confiance.
- L’auteur propose la définition de Jeffrey Liker pour la culture : “the pattern of basic assumptions… a given group has… to cope with the problems”.
- Exemple de culture d’absence de confiance dans une organisation : une organisation où toutes les équipes mettent place de l’over-engineering pour supporter un scale et une reliability non nécessaires, et ont peur de prendre des décisions communes avec les autres, parce qu’elles partent du principe que l’architecture mise en place par les autres ne sera pas à la hauteur.
- Dans une organisation avec une faible confiance, on peut être amené à cacher des informations ou bloquer des décisions pour exercer un contrôle.
- La confiance doit être cultivée : en fonction de la taille de l’entreprise, il faut doser les process pour l’alimenter sans trop limiter le flow.
- Les petites startups qui ont une culture de l’ownership collectif peuvent s’en sortir au début avec très peu de process. Ça marche parce que chacun se fait confiance. Tout le monde est autour de la table quand les décisions sont prises, quel que soit le mode de décision du moment, et tout le monde est aligné sur l’objectif.
- Une fois que le groupe grossit un peu trop (en gros, au delà de deux équipes agiles), un split subtile et graduel commence à se former : le groupe dominant qui a plus de pouvoir (contrôle de l’information et de l’accès aux ressources, sur le fait de fixer l’ordre du jour etc.), et qui en général ne s’en rend pas compte, et un ou plusieurs groupes périphériques qui le vivent assez douloureusement.
- Il s’agit d’un phénomène universel des groupes humains, décrit par exemple par Jo Freeman en 1972 dans The Tyranny of Structurelessness (opens in a new tab).
- Pour éviter que la confiance s’érode trop, il faut des éléments structurants plus formels : un processus de décision (dans notre cas l’advice process), et des mécanismes pour assurer la transparence et l’alignement (les ADRs comme un minimum, et les 4 autres éléments au besoin).
- En dehors des deux éléments formels et structurants que sont l’advice process et les ADRs, il faut bien savoir doser ce qu’on met en place en fonction de son contexte, pour que la confiance puisse prospérer.
- La nature et le nombre de ces éléments peut varier au cours du temps, en même temps que le contexte général du département tech et de l’entreprise. L’organisation doit donc apprendre et s’adapter en permanence.
- Il y a un risque non nul qu’on tende inconsciemment à ajouter de la structuration pour revenir à l’ancienne manière hiérarchique et bureaucratique. Il faut donc se demander à chaque fois si ça correspond à un vrai besoin.
- Exemple : l’auteur propose à une CTO cliente de mettre en place un meeting hebdomadaire pour aider à donner des advices. Elle lui fait remarquer que ça allait à l’encontre de leur culture remote et asynchrone. Finalement ils se sont interrogés sur le besoin réel, et se sont concentrés dessus. Ils ont fini par mettre en place un meeting de 30 minutes, avec une préparation avant ou après le meeting.
- L’exemple de Netflix permet de voir les choses du point de vue de la réduction de structuration : ils ont décidé d’enlever de la structure, jusqu’à obtenir le minimum nécessaire pour que ça fonctionne. Le résultat a été la responsabilisation de chacun.
- Il faut à chaque fois se demander si l’ajout d’un élément de structuration ne répond pas juste à un besoin de rendre les choses plus prédictibles. Cette pente est glissante.
- La solution est d’expérimenter les éléments régulièrement, un à la fois, et de voir s’ils améliorent le flow et la confiance dans l’organisation, ou non.
8 - An Architecture Advice Forum
- L’architecture Advice Forum est un meeting régulier qui permet à la fois de donner de l’espace pour l’advice process qu’on utilise déjà par ailleurs, et de le mettre en scène aux yeux de tous.
- Il augmente la confiance en rendant transparent en live une partie de l’application du process.
- Il ne s’agit pas de donner un nouveau nom aux meetings traditionnels d’architecture (Architecture Decision Forums ou Architecture Review Boards).
- Il n’y a pas de prise de décision ou de validation dans le meeting. L’advice process s’applique et les décisions reviennent à ceux qui les portent.
- On y trouve :
- 1 - Au moins un représentant par équipe jouant le rôle de partie affectée par les décisions.
- 2 - Les personnes avec de la connaissance domaine spécifique jouant le rôle d’experts à qui on demande souvent des advices. Par exemple des spécialistes UX, QA, InfoSec etc.
- Il met en scène des conversations qui ont généralement lieu en 1&1.
- Il permet à tous ceux qui regardent d’apprendre comment donner et demander des advices, mais aussi d’en apprendre plus sur thématiques spécifiques liées à l’architecture. C’est donc typiquement un meeting dont on tire bénéfice, même sans intervenir.
- Il encourage les désaccords sans avoir le côté “chercher à l’emporter” parce qu’il n’y a aucun enjeu de prise de décision dans le meeting.
- Les advices peuvent être donnés pendant ce meeting, mais aussi en dehors. Le meeting ne remplace pas l’advice process en 1&1, il vient lui donner un espace supplémentaire particulier, où le process a lieu sous les yeux de tous.
- Déroulé d’un Architecture Advice Forum :
- 1 - On établit un agenda pour le meeting, et on met ça dans une page de wiki. Chaque session a 3 catégories de sujets :
- Les ADRs qui ont besoin d’advices.
- Un suivi des ADRs des sessions précédentes dont le statut n’a pas bougé.
- “Any other business” : attention à ce que les sujets qui arrivent ici soient bien dans la thématique de l’advice process, il ne s’agit pas de dévier le meeting vers autre chose.
- 2 - On partage l’agenda. On fait appel à ceux qui veulent mettre leur ADR pour recevoir des advices, ou d’autres sujets. Des sujets seront probablement ajoutés y compris au dernier moment quand le meeting commence.
- 3 - Démarrer la session.
- On commence par passer en revue qui n’a pas pu être là. C’est important pour ne pas donner l’impression que présenter son ADR au forum est suffisant : il faut quand même aller chercher les advices de ceux concernés ou experts même s’ils n’ont pas pu être là.
- Ensuite on aborde la partie 1 avec ADRs qui ont besoin d’advices.
- 4 - La personne introduit son ADR.
- Elle présente les aspects les plus importants : le contexte, ce qui en fait une décision significative, ce qu’il a découvert d’intéressant, et ce sur quoi il aimerait des advices.
- 5 - Les personnes qui le veulent donnent des advices.
- C’est à la fois à la personne qui porte l’ADR de s’assurer qu’elle obtient bien des advices des personnes présentes qui seraient affectées par la décision ou expertes sur le sujet, et à la fois aux personnes en question d’intervenir pour donner l’advice.
- Le meeting n'exonère pas d’enregistrer l’advice dans l’ADR dans la section Advices. La personne qui porte l’ADR doit donc prendre des notes pour le faire plus tard.
- Tous les advices donnés doivent tous être enregistrés, que le porteur de l’ADR soit en accord avec l’advice ou non, et qu’il veuille l’incorporer au sein de l’ADR (en dehors de la section Advices) ou non.
- 1 - On établit un agenda pour le meeting, et on met ça dans une page de wiki. Chaque session a 3 catégories de sujets :