Charge Cognitive un driver de l'architecture

L'architecture est un élément clé dans la réalisation de tout projet, qu'il s'agisse d'un logiciel, d'un bâtiment ou d'un système complexe. Bien que la partie visible du travail de l'architecte se manifeste par des diagrammes et des représentations graphiques, cette discipline nécessite également une collaboration étroite avec d'autres équipes et parties prenantes. Au sein du contexte qui nous concerne, celui de l'informatique, l'architecture est directement liée aux flux de communications au sein de l'entreprise, comme l'énonce la Loi de Conway, et peut être influencée en utilisant des stratégies telles que la manœuvre inverse de Conway (cf. “Team Topologies”). Cependant, un facteur pouvant impacter significativement la mise en place et la maintenance de l'architecture est souvent négligé : la charge cognitive.

Dans cet article, nous allons définir ce qu'est la charge cognitive. Nous proposerons ensuite une méthodologie permettant d'estimer la charge cognitive lors de la conception de l’architecture en utilisant des modèles venant de “Team Topologies” et du “Domain Driven Design”.

Définition

La charge cognitive est un concept de plus en plus répandu. Elle représente la somme de la charge intrinsèque (ex : langages de développement), de la charge extrinsèque (ex : comment déployer mon service...) et de la charge essentielle (ex : contexte métier, complexité du domaine, lien avec les autres). En d'autres termes, la charge cognitive représente la quantité d'efforts mentaux que les membres de l'équipe doivent fournir pour réaliser leur travail.

Charge Cognitive = Charge Intrinsèque + Charge Extrinsèque + Charge essentielle

Cependant, la mesure de la charge cognitive est difficile, car elle dépend des individus. Les auteurs de "Team Topologies", Metthew Skelton et Manuel Pais, ont choisi de considérer la charge cognitive au niveau de l'équipe, c'est-à-dire la somme des charges cognitives de ses membres. Dans le cas où celle-ci est trop élevée, plusieurs conséquences deviennent visibles, comme le ralentissement des déploiements et le désengagement de l’équipe, pour n’en citer que deux. Ils l'utilisent comme un facteur potentiel déclencheur d'un changement d'organisation au niveau des équipes, dans une approche orientée "team first", afin que les équipes aient un domaine gérable à leur échelle. Dans cet article, nous nous intéressons à l’utilisation de la charge cognitive dans le cadre de la conception de l’architecture.

La charge cognitive peut devenir un outil, mais plusieurs questions se posent.

Comment la mesurer ? Comment l’utiliser ? Comment adapter ses capacités à cette charge cognitive ?

Comment la mesurer ? l’estimer ?

Étant donné que la charge cognitive n’est pas aisément quantifiable, il semble plus pragmatique de l’estimer.

Avant de pouvoir réaliser une estimation, il nous faut un modèle permettant de représenter ce que l’on souhaite estimer. Dans le cas de la conception/l’évolution de l’architecture, nous allons cibler la charge essentielle, qui est la partie de la charge cognitive que nous souhaitons estimer, car amenant le plus de valeur. Elle représente la complexité du domaine métier et de ses relations.

Charge essentielle ≃ Complexité du domaine & Complexité des relations

Dans la suite de l’article, nous mettons de côté, la charge intrinsèque d’une part, qui se doit d’être minimisée par exemple via des formations, et d’autre part la charge extrinsèque qui a vocation à disparaître dans l’idéal via de l’automatisation (cf. “Team Topologies”).

“Team topologies” propose déjà une méthode pour classifier la complexité relative des domaines en 3 catégories (simple, compliqué et complexe) basés sur différentes questions posées aux équipes. Cette méthode fonctionne seulement si les équipes et domaines existent déjà, ce qui n’est pas le cas d’une solution d’architecture à ses débuts (Green Field).

Nous allons proposer une méthode permettant d’estimer la charge cognitive, tout en gardant les catégories de mesures précédentes. L’objectif étant de pouvoir prendre en compte la charge cognitive comme un driver supplémentaire lors de la conception de l’architecture.

Pour avoir une estimation plus précise, nous partons du constat fait dans “Team Topologies”, en cherchant un modèle qui devra représenter les domaines et leurs relations. Lorsqu’on parle de domaine et de complexité, on entre dans le monde du Domain-Driven Design qui nous propose plusieurs modèles pour représenter les domaines et leurs types d’intéractions.

C’est ce que l’on cherche afin de démarrer notre estimation. Un modèle semble répondre à nos besoins : le Context Mapping.

Nous nous plaçons dans un monde idéal où les Bounded Context ne contiennent qu’un seul sous-domaine. Dans le reste de l’article, nous parlerons de domaine (<=> Bounded Context) afin de coller à la terminologie de “Team Topologies” et ainsi pouvoir utiliser leurs heuristiques que nous verrons dans la suite.

Figure 1 : Exemple de Context Mapping avec 3 domaines distincts en relation
Figure 1 : Exemple de Context Mapping avec 3 domaines distincts en relation

Sans rentrer dans toutes les spécificités du Context Mapping, nous utiliserons la figure 1 comme exemple dans tout le reste de l’article.

L’exemple modélise 3 domaines distincts : A, B, C avec différents types de relation.
Le domaine A expose un Open Host Service (OHS). Un OHS peut s’implémenter, par exemple, par un ensemble de services exposés via des API web.

Les domaines C et B sont dans une relation Upstream Downstream (U D) vis-à-vis du domaine A. Dans notre exemple, les données transitent de A vers B et C.

Dans le cas du domaine C, le pattern utilisé est celui dit conformist (CF), ce qui signifie que la complexité et les changements du domaine A se retrouvent tels quels dans le domaine C.
À l’opposé, le domaine B utilise le pattern Anti Corruption Layer (ACL) qui va diminuer l’impact en protégeant le domaine B.

Afin de pouvoir proposer une méthode permettant d’utiliser la charge cognitive dans la conception de l’architecture, sans équipes définies au préalable, nous venons de trouver un modèle via le Context Mapping. Ce modèle nous permet de représenter les domaines et leurs relations . Nous avons une base pour commencer à réfléchir sur comment estimer la complexité du domaine et de ses relations, soit les deux composantes de la charge cognitive essentielle qui nous intéresse.

Nous allons par la suite nous baser sur cet exemple sur lequel nous allons pouvoir nous exercer.

Estimation de la complexité du domaine

Maintenant que nous avons notre modèle de domaine représenté par le Context Mapping, nous pouvons procéder à une estimation relative de la charge cognitive essentielle. Plusieurs méthodes classiques peuvent être utilisées, nous opterons dans notre cas, en piochant dans la palette des outils du “DDD” pour le Core Domain Chart. Cette représentation utilise l'axe des ordonnées pour représenter la complexité relative du modèle des domaines défini dans le Context Mapping.

Figure 2 : Core Domain Chart Simplifié (Complexité relative)
Figure 2 : Core Domain Chart Simplifié (Complexité relative)

Dans notre exemple, en utilisant les mêmes termes que dans la méthode de mesure décrite dans “Team Topologies”, on se retrouve avec une complexité estimée au niveau du modèle pour le Domaine A, de complexe, le domaine B, de compliqué, et le domaine C, de simple.

Figure 3 : Complexité des domaines

Si nous nous arrêtons ici, nous avons une estimation de la complexité du modèle du domaine, ce qui représente une partie de la charge cognitive essentielle que l’on souhaite estimer. Une partie seulement, car on omet une partie aussi importante qui est celle des relations entre domaines.

Comment mesurer la complexité induite par ces relations entre domaines ?

Estimation de la complexité induite par les relations inter-domaines

Revenons sur notre exemple :

Figure 3 : Context Mapping avec complexité du modèle
Figure 3 : Context Mapping avec complexité du modèle

Il nous faut maintenant définir les règles pour prendre en compte la complexité induite par les relations. Grâce à la richesse du modèle du Context Mapping, nous pouvons nous baser sur les patterns et types de relations pour déduire et estimer l’impact au niveau de la complexité.

L’estimation qui suit se trouve être une proposition d’utilisation possible des patterns et relations du “DDD” et ne constitue pas une règle.

Le domaine C, de par sa position Downstream au sein de la relation Upstream Downstream et le pattern Conformist, se trouve être perméable à la complexité du domaine A, estimé à complexe.
On propose que la complexité induite par la relation pour le domaine C est estimée à celle de A, soit complexe.

En ce qui concerne le domaine B, il est aussi en relation avec le domaine A, mais avec un “ACL” qui va atténuer la complexité.
On propose que la complexité induite par la relation pour le domaine B ait le niveau en dessous de celui du domaine A, soit compliquée.
Pour terminer, le domaine A possède deux relations Upstream Downstream avec B et C n’ayant pas d’impact de son côté, on considère donc comme simple la complexité induite par la relation.

On obtient la matrice suivante pour la charge induite par les relations inter-domaines.

Complexité estimée induite des relations

Nous avons jusqu’à présent les deux composantes de la charge essentielle que nous voulions estimer, la complexité du modèle et la complexité des relations.

Estimation de la charge cognitive essentielle

Afin d’arriver à estimer la charge cognitive essentielle, il nous faut faire un choix relatif à la pondération des deux complexités que nous venons d’estimer. Nous choisirons, par simplicité, une pondération identique sur ces deux critères.

La charge cognitive essentielle sera égale à la moyenne entre la charge du modèle du domaine et celle induite par les relations.

Nous obtenons la matrice suivante pour notre exemple.

Charge Essentielle par domaine

Au final, on se retrouve avec les 3 domaines avec des charges compliquées, ce qui n’était pas visible au départ.

Comment utiliser ce résultat pour construire notre architecture et nos équipes ?

Comment utiliser la charge cognitive ?

La charge cognitive essentielle que nous avons pu estimer, avant l’existence des équipes, peut maintenant nous permettre d’appliquer, dès la conception, les différentes heuristiques proposées dans le livre “Team Topologies” :

Première heuristique : un domaine ne peut être assigné qu’à une seule équipe.

Deuxième heuristique : une équipe peut s’occuper de 2 ou 3 domaines avec une charge cognitive dite “simple”.

Troisième heuristique : une équipe ayant pour responsabilité un domaine avec une charge cognitive “complexe” ne peut pas s’occuper d’un autre domaine.

Dernière heuristique : une équipe ayant pour responsabilité un domaine avec une charge cognitive “compliqué” ne peut pas s’occuper d’un autre domaine “compliqué”.

En appliquant ces heuristiques à notre exemple, nous obtenons une organisation avec une équipe par domaine.

Figure 4 : Utilisation de la charge cognitive essentielle pour mapper les domaines aux équipes
Figure 4 : Utilisation de la charge cognitive essentielle

Comment faire si, par exemple, nous n’avons pas la capacité de fournir autant d'équipes.
Plusieurs solutions s’offrent à nous.

Adapter la charge cognitive essentielle à sa capacité

Diviser un domaine en deux plus simples

On peut essayer de diminuer la charge essentielle du domaine en le retravaillant afin d’avoir l’assurance qu’il n’a pas été complexifié.
Il est aussi possible de diviser un domaine compliqué en 2 domaines simples.
En appliquant cette stratégie à notre exemple, nous pouvons nous passer d’une équipe.
En effet, selon les heuristiques, une équipe en charge d’un domaine compliqué peut s’occuper d’un domaine simple (cf. Figure 5). On remarque que la division entraîne de nouvelles relations entre les domaines. La division fonctionne seulement si ces nouvelles dépendances n’augmentent pas, par effet de bord, la complexité.

Nouvelles charges essentielles par domaine après division

Figure 5 : Diminution de la charge cognitive essentielle via “division”, 2 équipes nécessaires
Figure 5 : Diminution de la charge cognitive essentielle via “division”, 2 équipes nécessaires

Fusionner les domaines

En cas de manque de ressources, il convient de noter que selon les heuristiques, la gestion d'un domaine complexe ne peut être assurée efficacement que par une seule équipe dédiée. Ainsi, une solution possible pour optimiser les ressources serait de fusionner les différents domaines en un seul domaine complexe.

Figure 6 : Monolithe
Figure 6 : Monolithe

Il est évident que la fusion de plusieurs domaines, en un seul complexe, peut avoir des conséquences néfastes sur l'équipe en charge à moyen terme. Il est à noter que les heuristiques et la charge cognitive sont des outils utiles pour prendre des décisions, mais ils ne doivent pas être appliqués sans prise de recul.

Il est important de comprendre que la charge cognitive ne se manifeste pas immédiatement, mais évolue au fil du temps. Dans le cadre de la réalisation d'un domaine monolithique, la charge peut être soutenable au début, mais à mesure que la complexité du domaine augmente, elle peut devenir de plus en plus difficile à gérer.

C'est pourquoi, cette solution n’est envisageable que si on adopte une approche progressive, en commençant petit, et en découvrant progressivement les différentes parties du domaine. Si le découpage est bien fait, en utilisant une architecture de la famille de la Clean Architecture, avec des séparations entre les domaines respectées, rien n'empêche, à mesure que la charge cognitive augmente, de recruter, et de créer un nouveau domaine en utilisant la technique précédente de la “division”.

Conclusion

La méthodologie de mesure de la charge cognitive proposée dans “Team Topologies” suppose que les équipes soient déjà présentes.
Ce que nous avons vu dans cet article est une proposition de méthodologie permettant de mesurer la charge cognitive, dès la conception de l’architecture, et avant la création des équipes. La méthodologie se base sur des concepts venant du “DDD”, avec l’utilisation du Context Mapping, puis du Core Domain Chart, complémentaires à celle de “Team Topologies”. En utilisant les heuristiques proposées dans le livre "Team Topologies", il est ensuite possible de faire correspondre les domaines, aux équipes, de manière à réguler leur charge cognitive. Toutefois, il est important de garder à l'esprit que la charge cognitive évolue au cours du temps et qu'il est nécessaire d'adapter l'architecture en conséquence.

En conclusion, la charge cognitive est un critère pouvant être pris en compte tout au long du cycle de vie de l’architecture logicielle afin de faire évoluer, avec le moins de friction, l’organisation des équipes.