Styles et modèles d'architecture

Un architecte dispose d’un certain nombre d’outils pour structurer ses études. Les concepts de style d’architecture (architecture styles), de modèle d’architecture (architecture pattern), et de modèle de conception (design pattern) y tiennent une place prépondérante. Ils constituent, à la fois des outils techniques, en proposant des solutions éprouvées, mais également des outils de communication, en fournissant une base de travail, et un vocabulaire commun.

Styles et modèles d'architecture

Dans une entreprise, les architectes n’ont pas toujours bonne réputation, parce que lorsqu’ils (re)prennent un sujet, ils arrivent toujours avec des principes des standards, et des patterns (modèles). Quelque chose de simple, imaginé par l’utilisateur, ou le développeur, devient soudainement plus compliqué.

Mais ces principes, standards, et modèles sont nécessaires, car ils soutiennent une démarche qui consiste, non seulement à répondre aux besoins du sujet en cours, mais surtout

  • à s’assurer que TOUS les besoins fonctionnels, et non-fonctionnels (haute disponibilité, performances, …) sont bien pris en compte,
  • à fournir une architecture qui est cohérente avec l’écosystème de l’entreprise, qui est maintenable, et qui est non-bloquante pour les futurs besoins de l’entreprise,
  • et finalement à pérenniser l’application.

Après cette petite parenthèse qui fera sourire certains de mes collègues, entrons dans le vif.

En introduction, j’ai parlé de style d’architecture, de modèle d’architecture, ou de modèle de conception. Il existe en fait, un certain nombre de concepts ayant chacun un rôle dans chacune des étapes d’un projet, depuis le tout début de l’étude d’architecture, jusqu’au développements.

Les styles d’architecture (architectural styles)

Un style d’architecture (Architecture style) décrit la structure globale d’une plateforme, ou d’un système.

Les styles d’architecture constituent le point de départ d’une étude d’architecture. Ils permettent

  • De donner une ligne directrice à l’étude d’architecture,
  • De définir une base de travail aux membres de l’équipe d’architecture.

Nous pouvons regrouper les styles d’architecture selon deux grands axes de classification :

  • Une classification par structure : les architectures monolithiques, et les architectures distribuées,
  • Une classification par partitionnement, avec des architectures qui peuvent être organisées par fonction technique, ou par domaine fonctionnel.

Figure 1 : Les styles d’architectures - CC [BY-NC 4.0]
Figure 1 : Les styles d’architectures - CC [BY-NC 4.0]

Les architectures monolithiques, et distribuées

Les architectures monolithiques sont constituées, comme leur nom l’indique, d’un bloc applicatif unique, alors que les architectures distribuées sont constituées d’un ensemble de blocs qui fonctionnent ensemble pour exécuter une ou un ensemble de fonctions métier cohérentes (figure 2).

Figure 2 : Les architectures monolithiques et distribuées - CC [BY-NC 4.0]
Figure 2 : Les architectures monolithiques et distribuées - CC [BY-NC 4.0]

Architecture par fonction ou par domaine fonctionnel

Dans les architectures partitionnées par fonctions techniques, les blocs / services sont regroupés par fonction / rôle. La figure 3 montre un exemple classique, avec une architecture multicouche (layered architecture).

Dans les architectures partitionnées par domaines fonctionnels, chaque bloc / service fournit un service lié à un domaine précis. Dans une application gérant les commandes et les relations client, on peut imaginer un bloc customer pour gérer les clients, un bloc Booking pour les commandes, un bloc Billing pour gérer les facturations …

Figure 3 : Style d’architecture partitionné par fonction technique et par domaine fonctionnel - CC [BY-NC 4.0]
Figure 3 : Style d’architecture partitionné par fonction technique et par domaine fonctionnel - CC [BY-NC 4.0]

Quelques exemples de styles d’architecture

StyleDescription
MonolithicUn seul composant logiciel, implémentant plusieurs services
LayeredArchitecture organisée en couches techniques
MicrokernelArchitecture basée sur un composant central, et sur la notion d’extensions (plug-ins)
Event-drivenCoordination asynchrone des différents composants, basée sur l’échange de messages / d’évènements
MicroserviceArchitecture composée de services assurant chacun une fonction unique, et communicant à travers une API
Space-basedPermet de gérer de très gros volumes de transactions, ou des services faisant face à un très grand nombre d’utilisateurs

Notion de « pattern »

Les modèles en général

D’un point de vue général, un pattern (patron, modèle, ou motif en français) est une idée qui a été utile pour un sujet donné, et qui pourra probablement être utile pour d’autres sujets.

Cette phrase très génétique comporte trois points importants :

  • Un modèle est une solution qui a déjà fonctionné,
  • Dans le cadre d’un sujet précis,
  • Et cette solution est réutilisable.

Cette notion n’est pas nouvelle : elle est apparue dans les années 1970, dans le domaine du développement logiciel. La référence souvent citée est le livre Design patterns : elements of reusable object-oriented software des quatre auteurs : Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides. Ces auteurs sont souvent regroupés sous le terme GoF (Gang of Four, la bande des quatre).

Pour le framework TOGAF®, la définition est très proche :

Un modèle est une façon d’utiliser des blocs d’architecture (building blocks) dans un contexte donné. Un modèle (pattern) est une solution réutilisable. Face à un problème ou une typologie de problèmes, les modèles (patterns) nous aident à sélectionner des combinaisons d’architecture, ou des blocs, qui se sont avérés être des solutions efficaces dans le passé et qui peuvent fournir, à l’avenir, la base de solutions pour des problèmes équivalents. 1

Les modèles nous indiquent

  • Quels blocs d’architecture utiliser,
  • Quand, comment, et pourquoi les utiliser, et quels sont les éventuels compromis possibles.

Quand nous parlons de modèle, nous parlons en fait, de trois concepts, de niveau différent 2

  • Les modèles d’architecture (architectural patterns),
  • Les modèles/motifs de conception (design patterns),
  • Les motifs de codage (idioms)

Les modèles d’architecture

Les modèles d’architecture (architectural patterns) sont des modèles de haut niveau. Ils aident à concevoir / structurer / organiser, à grande échelle, un système informatique. Ces modèles indiquent comment organiser une structure complexe en sous-systèmes, quand et comment utiliser ces sous-systèmes, et comment les relier entre eux.

Pour résumer, ces modèles aident à construire le design des styles d’architecture sélectionnés.

La figure 4 par exemple, décrit un modèle appelé CQRS (Command and Query Responsability Segregation), qui consiste à dédier une partie de l’architecture aux transactions en écriture, et une autre partie aux transactions en lecture.

Figure 4 : Exemple de modèle d’architecture. Le modèle CQRS (Command and Query Responsibility Segregation) - CC [BY-NC 4.0]
Figure 4 : Exemple de modèle d’architecture. Le modèle CQRS (Command and Query Responsibility Segregation) - CC [BY-NC 4.0]

Il existe un assez grand nombre de modèles d’architecture, nous pouvons citer comme exemple

ModèleDescription
CQRSCommand and Query Responsibility Segregation
MVCModel-View-Controler
MVVMModel View View-Model
MVPModel View Presentation
VIPERVisually Interesting Planned Easy Roadtrips

Les modèles de conception

Les modèles de conception, ou motifs de conception (design patterns) sont apparus en premier, et dans le domaine du développement logiciel. Ils s’adressent principalement aux développeurs, et permet, face à un problème donné, de sélectionner la bonne approche.

Nous distinguons trois familles de patterns

  • Création : description de la manière dont un objet peut être créé et isolation du code relatif à la création,
  • Structure : description de la manière dont doivent être connectés les objets de l’application afin de rendre ces connexions indépendantes de futures évolutions,
  • Comportement : description de comportements d’interaction entre objets

Figure 5 : Exemple de motif de conception, DocumentFactory - CC [BY-NC 4.0]
Figure 5 : Exemple de motif de conception, DocumentFactory - CC [BY-NC 4.0]

CréationStructureComportement
Abstract FactoryAdapter bridgeChain of responsability
BuilderCompositeIterator
PrototypeDecoratorMediator
SingletonFacadeMemento
FlyweightObserver
ProxyState
Strategy
Visitor
Command

Les idioms

Les motifs de codage, ou patrons de codage (idioms) est une construction spécifique à un langage de programmation. Ces modèles montrent les manières usuelles de mettre en œuvre une solution à un problème dans ce langage de programmation. Le code ci-dessous donne un exemple d’idiom avec Python :

>>> z = [ 'a', 'b', 'c', 'd' ]

# First way to enumerate the list
>>> i = 0
>>> while i < len(z):
...    print i, z[i]
...    i += 1

# Another way to enumerate a list
>>> for i in range(0, len(z)):
...    print i, z[i]

# The best way to proceed: the idiom.
>>> for i, item in enumerate(z):
...    print i, item

Il existe d’autres catégories de modèles qu’il est inutile de détailler ici. Je vais juste m’attarder sur les anti-patterns.

Les anti-modèles

Les anti-modèles sont des modèles dont le choix apporte plus de problèmes qu’il n’en résoud. Ce sont de mauvais choix de structure, ou d’organisation, faits lors de la conception, et qui conduisent à des disfonctionnements. Ces anti-modèles sont finalement, de véritables modèles en montrant ce qu’il ne faut pas faire.

Figure 6 : Un exemple d’anti-pattern (et de la bonne pattern en pointillé) - CC [BY-NC 4.0]
Figure 6 : Un exemple d’anti-pattern (et de la bonne pattern en pointillé) - CC [BY-NC 4.0]

J’ai cité le concept d’anti-pattern, parce qu’il me semble important de souligner que l’utilisation de patterns n’est pas sans risques, et qu’il faut donc les utiliser de façon réfléchie :

  • L’avantage des modèles est facilement compréhensible : ce sont des idées qui fonctionnent, qui garantissent la standardisation, et la robustesse des systèmes d’information. Ces modèles accélèrent également les phases de conception,
  • Mais il n’existe pas forcément de modèles à tous les problèmes, et il faut surtout veiller à ce que le problème que vous traitez corresponde bien aux conditions d’utilisation des modèles que vous ciblez. Un mauvais choix de modèle peut conduire à des disfonctionnements de votre système. Et comme l’erreur a lieu pendant la conception, et la détection des disfonctionnements, à la fin du codage, les conséquences de cette erreur peuvent être assez lourdes,
  • Et il faut être vigilant également au phénomène d’over-design qui consiste à construire, pour un sujet donné, une solution trop complexe, ou disproportionnée.

Résumé : Avantages et risques

Pour résumer, l’utilisation de styles, modèles, motifs, …

  • Accélère la phase de conception,
  • Contribue à la standardisation et la fiabilité des plateformes,
    • Cette standardisation est bénéfique à toutes les étapes : conception, mais surtout déploiement, et exploitation.
  • Permet d’avoir une meilleure connaissance de ces plateformes : ré-utiliser plusieurs fois les mêmes blocs permet d’en connaître les forces, et les faiblesses,
  • Si l’entreprise dispose d’un dictionnaire ou d’un référentiel de ces patterns :
    • Le choix d’un modèle en phase de conception devient plus fiable, puisque nous disposons d’une liste de cas d’utilisation, que nous pouvons comparer avec le cas étudié,
    • Si nous rencontrons un problème avec un bloc, pendant la phase d’exploitation (performance, fiabilité, sécurité, …), nous pouvons facilement identifier toutes les plateformes utilisant le même modèle, et donc effectuer des corrections exhaustives,

Mais leur utilisation ne se fait pas sans risques :

  • Lors de la conception, le choix d’un modèle non adapté, conduira à une refactorisation (rework, relayout, …) de la plateforme, avec des conséquences sur les coûts, les délais, …
  • Nous pouvons avoir une sorte « d’effet tunnel » : lors de la conception, nous pouvons rester focaliser sur la réutilisation de blocs disponibles, sans voir des solutions plus simples ou plus efficaces,
  • Attention à l’effet de concentration : Si le modèle utilisé correspond concrètement à un composant, la réutilisation massive du modèle, contribue à rendre le composant critique pour l’ensemble du système d’information. Exemple : Si tous les échanges entre composants passent par un ESB (Enterprise Service Bus), le taux de disponibilité, la performance de cet ESB deviennent critiques, avec de multiples conséquences au niveau de son coût, et de son exploitation.

Il existe des approches pour réduire ces risques :

  • Pendant la phase d’étude, lors de la phase d’identification des hypothèses, il peut être intéressant de systématiser l’ajout d’une ou plusieurs hypothèses n’utilisant pas de pattern (Think out of the box),
  • Lors de la création d’un nouveau modèle / pattern, il est important d’ouvrir un chapitre sur l’utilisation « à l’échelle » de ce modèle, en se posant des questions, notamment sur son implémentation, et son exploitation (à l’échelle d’un département, d’une organisation, de l’entreprise, …), de ces limites, … Dans cette phase-là, ouvrir l’étude à des architectes techniques, à des administrateurs, ou des développeurs, est indispensable.

Styles et modèles, quand les utiliser ?

Durant une étude d’architecture, nous avons toujours plusieurs phases

  • Collecte des besoins fonctionnels et non-fonctionnels,
  • Définition de l’approche globale : Liste des points d’attention, des options possibles, choix du ou des styles d’architecture,
  • Description du high-level design (design global) : en travaillant sur les brouillons produits à la phase précédente, par itérations successives, les hypothèses se précisent, ainsi que les choix de styles, et de modèles,
  • Définition de l’architecture technique détaillée (Low Level design) : Cette dernière étape consiste à descendre dans les détails, pour confirmer les modèles, et fournir un document qui puisse être repris par tech lead, et les développeurs.

Nous pouvons aligner les étapes, et les différents styles et modèles (figure 7).

Figure 7 : The Squiggle - CC [BY-NC 4.0]
Figure 7 : The Squiggle - CC [BY-NC 4.0]

Styles d’architecture / Modèle d’architecture / Modèle de conception

Dans les paragraphes précédents, j’ai bien différencié style d’architecture et modèle d’architecture. Mais cette distinction est finalement très théorique, et si vous lisez d’autres articles, vous ne retrouverez probablement pas la même classification. Le terme de style d’architecture est relativement récent. Son utilisation n’est pas très répandue, et beaucoup utilisent les deux termes indifféremment, en les considérant comme équivalents. Nous avons, dans une moindre mesure, le même type de questions pour différencier modèle d’architecture, et modèle de conception. 34

J’ai choisi de différencier les trois termes, parce que j’ai personnellement du mal à regrouper dans la même catégorie

  • Des concepts d’architecture tels que les architecture monolithiques, multicouches, SOA, micro-services, …
  • Des concepts comme MVC (Model / View / Control), ou CQRS (Command Query Responsibility Segregation),
  • Et des motifs comme Decorator, Factory, …

Ces trois concepts n’ont pas le même niveau d’abstraction, n’ont pas le même rôle, et ne sont pas utilisés aux mêmes étapes. Concrètement, un style d’architecture ne résout pas une problématique. Il s’agit plus de la description d’une structure, ou d’une approche, alors que les modèles d’architecture, et les motifs de conception résolvent des problématiques liées au sujet, ou des problématiques récurrentes, et sont orientés « implémentation ».

Le tableau suivant, ainsi que la figure 8 proposent une comparaison de ces trois concepts, tels que je les ai décrit dans cet article. Dans d’autres articles, le terme modèle d’architecture (architecture pattern) regroupera indiféremment les styles, et les modèles.

Styles d’architectureModèle d’architectureModèle de conception
RôleStructure globale / stratégie d’une application ou d’un système d’informationAide à la structuration de l’applicationAide à l’implémentation
DomaineStructureDesignImplémentation
NiveauSystèmes / ApplicationsApplications / ModulesModules / Codes
Etape
  • Début de l’étude d’architecture
  • Choix de la stratégie
  • Phase d’étude technique
  • High-Level design
  • Low-Level design
  • Implémentation/Codage
Description
  • Décrit une structure / une stratégie
  • Ne résout pas de problème spécifique
  • Répond à une problématique
  • Décrit l’implémentation du style d’architecture sélectionné
  • Répond à une problématique
  • Décrit une structure de code / de données

Figure 8 : Styles d’architecture / Modèle d’architecture / Modèle de conception - CC [BY-NC 4.0]
Figure 8 : Styles d’architecture / Modèle d’architecture / Modèle de conception - CC [BY-NC 4.0]

A noter qu’il n’y a pas de relations spécifiques (ni 1-1, 1-n, n-1) entre les styles d’architecture, les modèles d’architecture, et les modèles de conception. Un modèle d’architecture peut-être tout à fait être utilisé pour l’implémentation d’architectures de plusieurs styles. Il en va de même entre les modèles d’architecture et de conception.

Contenu des modèles

Nous venons de voir ce que sont les modèles. Nous allons étudier maintenant, quelles informations doivent accompagner un modèle, dans l’optique de se constituer une bibliothèque.

Description

Un modèle ne se résume pas à une représentation graphique. La littérature propose de très nombreux formats, et il n’existe pas réellement de « standard ». Basé sur le livre Pattern-Oriented Software Architecture: A System of Patterns (Buschmann et al., 1996), TOGAF® propose les éléments de contenu suivant 2:

ChampDescription
NomL’identifiant du modèle. Ce nom doit être facilement mémorisable, et doit identifier le contenu
DescriptionQuelques phrases décrivant le problème posé, et la façon dont le modèle le résout
Le contexteLes conditions d’application du modèle. L’état initial
Le problèmeUne description exhaustive du problème, avec ses challenges, et ses contraintes. Cette description doit faire référence aux points d’optimisation que recherchent les architectes, comme :
  • La sécurité,
  • La robustesse, la tolérance aux pannes, …
  • Les performances, les problèmes de dimensionnement
  • L’évolutivité
  • L’intégration
La solutionUne description complète de la solution. Cela peut être du texte et/ou des schémas. Cette description doit inclure l’ensemble des éléments de la solution : les composants impliqués, leurs interactions, les intervenants, … Elle doit également inclure le mode d’implémentation, ainsi que les variantes possibles
Le résultatLe résultat attendu, l’état final, après application du modèle. Cette description doit donner les éléments du problème qui sont résolus, et les éléments qu’ils ne le sont pas
Motivations(rational) La justification du modèle : en quoi le modèle résout le problème posé, et comment il fonctionne.
Autres modèlesLes liens qui peuvent exister entre le modèle décrit, et d’autres modèles
Cas d’usage connusLes applications connues du modèle dans les systèmes d’information de l’entreprise. Cette liste de cas doit montrer l’efficacité du modèle dans des cas réels. Certains cas peuvent servir d’exemple
ExemplesUn ou plusieurs exemples d’utilisation du modèle. Ces exemples doivent montrer le problème initial, et la façon dont le modèle le résout

Cette liste est loin d’être exhaustive : nous pouvons y ajouter, en fonction des cas,

  • Les évolutions possibles du modèle,
  • Les options évaluées, mais non retenues, lors de la conception du modèle,
  • Des informations relatives au niveau de service fournis, aux seuils éventuels d’utilisation (capacité maximum du modèle), aux performances attendues,
  • Des détails concernant l’implémentation, avec des références aux designs patterns ou aux axiomes recommandés,
  • … …

L’essentiel est de fournir les conditions d’utilisations du modèle : Quels sont les cas d’usage ? Quel est le domaine d’utilisation (les limites) ?

Représentation graphique d’une architecture

L’utilisation des patterns lors de la conception d’une architecture est un gain de temps et d’efficacité. Il en va de même pour la description graphique : modéliser une architecture en assemblant les représentations des blocs d’architecture (building block) utilisés, permet un travail beaucoup plus rapide, et moins fastidieux.

Disposer d’une bibliothèque de représentation de nos modèles apporte d’autres avantages :

  • La réutilisation des schémas conduit à une certaine « standardisation », ce qui conduit à une meilleure compréhension de la part de nos interlocuteurs,
  • Si les représentations sont bien faîtes, elles peuvent inclure les contraintes d’intégration, et permettent donc de repérer les erreurs au niveau de la conception.

Quel langage ?

Il existe de multiples langages de représentation graphique, et comme pour les autres langages informatiques, ils ont un domaine d’utilisation / de prédilection.

Personnellement, je ne pense pas que l’on puisse gérer l’intégralité d’une étude d’architecture avec un unique langage, parce que les schémas et représentations doivent s’adresser à un large panel d’interlocuteurs aux profils variés.

Utiliser un langage unique serait intéressant, parce que

  • Nous aurions une normalisation des représentations, de bout en bout,
  • Et un unique langage pour toute la communauté des architectes.

Mais

  • Est-on sûre que ce langage unique soit compris par les personnes extérieures à cette communauté ?
  • Un langage unique obligera probablement à faire des compromis sur certaines représentations.

Une approche multi-langages pourrait être (figure 9),

  • Le langage BPMN (Business Process Model and Notation) pour une description des processus « métiers » lors des premières phases,
  • Le langage Archimate pour les phases intermédiaires,
  • Le langage UML, ou équivalent pour la phase finale, et les discussions avec les développeurs.

Figure 9 : Le domaine d’utilisation de Archimate® - CC [BY-NC 4.0]
Figure 9 : Le domaine d’utilisation de Archimate® - CC [BY-NC 4.0]

Le langage BPMN peut être compris assez facilement par les utilisateurs pendant les premières phases de démarrage, et le langage UML permet de descendre facilement dans les détails de l’implémentation avec les développeurs.

Rien n’empêche l’utilisation de représentation graphique « maison », l’important étant d’avoir une compréhension commune avec vos interlocuteurs.

Réutilisation des patterns

Trois points permettent de rendre un modèle réellement réutilisable :

  • La clarté, et l’exhaustivité de sa documentation,
  • Sa facilité d’intégration avec les autres modèles et composants : il faut pour cela que les architectes puissent rapidement identifier, et comprendre les interfaces,
  • Sa simplicité graphique.

En se basant sur le concept de « vue » du langage Archimate®, nous pouvons fournir plusieurs vues du même modèle, avec au moins une vue détaillée, et une vue simplifiée (figure 10).

Figure 10 : Vue détaillée, et vue simplifiée - CC [BY-NC 4.0]
Figure 10 : Vue détaillée, et vue simplifiée - CC [BY-NC 4.0]

La vue détaillée (figure 11 à gauche) permet

  • De comprendre le fonctionnement du modèle.
  • D’extraire des spécifications (en exportant le modèle au format CSV Excel, ou autre …) (figure 12),
  • De montrer les points de complexité ou les points d’attention.

La vue simplifiée (figure 11 à droite)

  • Permet d’intégrer facilement le modèle dans l’architecture,
  • Sans encombrer le schéma,
  • Les éléments service et interface servent de points d’intégration avec les autres composants de l’architecture.

Figure 11 : Un exemple d’un modèle de serveur physique - Vue détaillée et simplifiée - CC [BY-NC 4.0]
Figure 11 : Un exemple d’un modèle de serveur physique - Vue détaillée et simplifiée - CC [BY-NC 4.0]

Figure 12 : La liste des composants, avec des spécifications (export Excel) - CC [BY-NC 4.0]
Figure 12 : La liste des composants, avec des spécifications (export Excel) - CC [BY-NC 4.0]

La figure 13 montre comment le modèle peut être utilisé en considérant la vue simplifiée :

Figure 13 : Utilisation du modèle - CC [BY-NC 4.0]
Figure 13 : Utilisation du modèle - CC [BY-NC 4.0]

Généralisation

En généralisant ce principe, nous pouvons obtenir la description complète d’une architecture par l’assemblage de modèle, dont l’intégration se fait via les éléments Interface, ou Service (figure 14).

Figure 14 : Modèle complet de la couche Business, jusqu’à la couche physique, avec intégration - CC [BY-NC 4.0]
Figure 14 : Modèle complet de la couche Business, jusqu’à la couche physique, avec intégration - CC [BY-NC 4.0]

Conclusion

Nous venons de découvrir les concepts de style et modèle d’architecture. Même si ces définitions peuvent varier d’un article à un autre, il faut retenir quelques points principaux :

Pour une entreprise

  • Une architecture basée sur des modèles sera toujours plus efficace et mieux acceptée,
  • Les modèles seront d’autant mieux acceptés, qu’ils sont discutés avec les différentes équipes (architectes, développeurs, support/ maintenance, …)
  • Utiliser des modèles est bénéfique dans toutes les étapes d’un projet, y compris pendant les phases de déploiement et de maintenance,
  • Constituer une bibliothèque de styles et de modèles, est un point de cohérence majeure.

Pour les équipes de développement

  • L’utilisation de modèle d’architecture est autant un outil de communication entre les architectes et les développeurs, qu’un outil technique,
  • L’utilisation de modèle de conception est un bon moyen de fournir un code robuste, et de limiter les risques d’erreur.

Attention au risque d’anti-pattern

  • Un modèle n’est efficace que s’il est utilisé pour les bons cas d’usages,
  • La mauvaise utilisation d’un modèle, ou une erreur dans le choix d’un modèle peut conduire à l’effet inverse.

Je reviendrai probablement, dans de prochains articles, sur des styles, et modèles courants.

Références

Commentaires