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 :