Un style architectural est une classe générique d - Latece

Transcription

Un style architectural est une classe générique d - Latece
Les langages de description d’architectures
Ghizlane El Boussaidi
[email protected]
Hafedh Mili
[email protected]
LAboratoire de recherche sur les TEchnologies du Commerce Electronique
Université du Québec à Montréal
Abstract
Architectural description is a central artifact in software design. Indeed, architecture provides a high
level description of a system’s structure which reduces its complexity. Hence it is essential to have languages
enabling precise specification of architectural descriptions. In this report, we review formal architectural
description languages and we also look at the UML2.0 mechanisms that support architectural modeling.
Résumé
La description architecturale est un artefact central dans la conception logicielle. En effet,
l’architecture fournit une description de haut niveau de la structure d’un système ce qui permet de réduire sa
complexité. Il est donc essentiel de disposer de langages permettant la spécification précise des descriptions
architecturales. Dans ce rapport, nous passons en revue des langages formels de description d’architectures
et nous nous penchons aussi sur les mécanismes fournis par UML2.0 pour modéliser les architectures.
LATECE Technical Report, October 2006
Page 1
Table des matières
1. Introduction _____________________________________________________ 3
2. Style architectural ________________________________________________ 4
2.1
Définition _____________________________________________________________________________ 4
2.2
Exemple de style architectural : Filtres et Canaux____________________________________________ 4
3. Les langages de description d’architecture (ADLs) ______________________ 5
3.1
Concepts de base _______________________________________________________________________ 6
3.1.1
Les exigences minimales fondamentales__________________________________________________ 6
3.1.2
Les exigences souhaitables : ___________________________________________________________ 7
3.1.3
Les exigences désirables mais non fondamentales : _________________________________________ 7
4. Survol des ADLs _________________________________________________ 8
4.1
Les ADLs se concentrant sur l’aspect structurel _____________________________________________ 8
4.1.1
Wright ____________________________________________________________________________ 8
4.1.2
ACME ___________________________________________________________________________ 13
4.1.3
UniCon __________________________________________________________________________ 17
4.1.4
Aesop____________________________________________________________________________ 22
4.1.5
C2 ______________________________________________________________________________ 24
4.2
Les ADLs se concentrant sur l’aspect dynamique ___________________________________________ 29
4.2.1
Darwin ___________________________________________________________________________ 29
4.2.2
RAPIDE _________________________________________________________________________ 33
5. Synthèse sur les ADLs ____________________________________________ 36
6. La description architecturale dans UML _____________________________ 39
6.1
Présentation sommaire d’UML __________________________________________________________ 39
6.2
Les approches basées sur UML1.x________________________________________________________ 40
6.3
UML2.0______________________________________________________________________________ 43
6.3.1
Le modèle de composant _____________________________________________________________ 43
6.3.2
Le modèle de déploiement____________________________________________________________ 49
6.3.3
Le modèle comportemental ___________________________________________________________ 52
6.4
UML2.0 comme ADL __________________________________________________________________ 54
7. Conclusion _____________________________________________________ 55
8. Références _____________________________________________________ 55
LATECE Technical Report, October 2006
Page 2
1.
Introduction
Une étape des plus importantes et critiques dans le processus de conception d’un système est la
conception architecturale. En effet, l’architecture fournit la description de haut niveau de la structure d’un
système ce qui permet de réduire sa complexité. « L’architecture logicielle inclut la description des éléments
à partir desquels les systèmes sont construits, les interactions entre ces éléments, les patrons qui guident leur
composition et les contraintes sur ses patrons » (Garlan et Shaw, 1994). Ainsi, la conception architecturale se
base sur des patrons récurrents d’organisation appelés styles architecturaux.
Vu le rôle important que l’architecture joue dans le développement de systèmes complexes, il est
devenu indispensable de disposer de langages pour la spécifier de façon précise. Pour cela, plusieurs
formalismes de description d’architectures ont été proposés par la communauté de recherche en architecture
logicielle, on les appelle les langages de description d’architectures (ADL : Architecture Description
Language). « Un ADL se concentre plutôt sur la structure de haut niveau de l’ensemble de l’application, que
sur les détails d’implémentation. » (Vestal, 1993). Les plus connus de ces langages sont Wright (Allen,
1997), ACME (Garlan et al., 2000), Rapide (Luckham et al., 1995), UniCon (Shaw et al., 1995), C2 (Taylor
et al., 1996), Darwin (Magee et al., 1995) et AESOP (Garlan et al., 1994). Les ADLs proposent des notations
formelles pour décrire les concepts de la description architecturale et permettent des analyses rigoureuses des
architectures. Cependant, chaque ADL se concentre sur une famille spécifique d’architectures et offre un
langage de modélisation et des techniques d’analyse fortement spécialisés. Ce traitement en profondeur et
cette rigueur offerts par un ADL peuvent rendre difficile l’intégration des descriptions architecturales avec
d’autres artefacts de développement (Medvidovic et al., 2002).
D’autres travaux (Medvidovic et al., 2002), (Garlan et al., 2002) (Baresi et al., 2003) (PerezMartinez, 2003) (Zarras et al. 2001) se sont intéressés aux aptitudes du langage UML à modéliser les
architectures logicielles et ont proposé quelques alternatives et extensions. Cet intérêt a été motivé par la
familiarité des concepteurs et développeurs avec UML et aussi la disponibilité d’outils de modélisation
supportant UML. Cependant, UML n’offre pas la rigueur ni les possibilités d’analyses offertes par les ADLs.
Dans ce rapport nous nous intéressons au support offert par les ADLs et par UML pour la description
architecturale. Le document est organisé de la manière suivante. Nous commençons par définir un style
architectural et illustrer cette notion par un exemple. Nous introduisons ensuite à la section 3 les concepts
sous-jacents à la description architecturale et qui doivent être modélisés par les ADLs. Nous faisons un
survol des ADLs les plus communs dans la section 4 et nous les comparons à la section 5. Dans la section 6,
LATECE Technical Report, October 2006
Page 3
nous présentons et discutons des mécanismes offerts par UML pour supporter la description architecturale.
Nous concluons à la section 7.
2.
Style architectural
2.1
Définition
« Les styles architecturaux forment un répertoire de base des architectures » (Garlan et Shaw, 1994).
En fait, un style architectural peut être considéré comme une classe générique d’architecture ou un patron
d’organisation (exemple : « client-serveur », « filtres et canaux », « architecture par couches », etc.). Il
définit les propriétés pour les éléments de conception, les règles et les contraintes sur la façon de les lier
(contraintes topologiques) et permet des analyses spécialisées et spécifiques au style. « Un style architectural
peut être défini comme un type que l’architecture doit avoir pendant l’exécution » (Le Métayer, 1998). Les
éléments du système ne peuvent interagir qu’à travers les liens spécifiés par le style.
Un style architectural inclut une spécification statique et une spécification dynamique. La partie
statique englobe l’ensemble des éléments (composants et connecteurs) et des contraintes sur ces éléments. La
partie dynamique décrit l’évolution possible d’une architecture en réaction à des changements prévus ou
imprévus de l’environnement. Selon (Garlan et Shaw, 1994), un style architectural est précisément défini par
un ensemble de caractéristiques telles que : le vocabulaire utilisé (les types de composants et de
connecteurs), les contraintes de configuration (contraintes topologiques appelées aussi patrons structurels),
les invariants du style, les exemples communs d’utilisation, les avantages et inconvénients d’utilisation de ce
style et les spécialisations communes du style. Un style architectural spécifie aussi les types d’analyse que
l’on peut faire sur ses instances (systèmes construits conformément à ce style).
2.2
Exemple de style architectural : Filtres et Canaux
Un des styles architecturaux les plus communs est le style « Filtres et Canaux » (pipes and filters).
Dans ce style, un composant reçoit un ensemble de données en entrée et produit un ensemble de données en
sortie. Le composant lit continuellement les entrées sur lesquelles il exécute un traitement ou une sorte de «
filtrage » pour produire les sorties. Pour cela, les composants sont appelés filtres (Garlan et Shaw, 1994). Les
spécifications des filtres peuvent contraindre les entrées et les sorties. Un connecteur, quant à lui, est appelé
« Canal » puisqu’il représente une sorte de conduite qui permet de véhiculer les sorties d’un filtre vers les
entrées d’un autre. Le style « Filtres et Canaux » exige que les filtres soient des entités indépendantes et
qu’ils ne connaissent pas l’identité des autres filtres. De plus, la validité d’un système conforme à ce style ne
LATECE Technical Report, October 2006
Page 4
doit pas dépendre de l’ordre dans lequel les filtres exécutent leur traitement. Parmi les exemples les plus
connus de systèmes conformes à ce style, on peut citer les programmes écrits en Unix. La Figure 1
représente un exemple simple (séquence linéaire de filtres) du style « Filtre et Canal » où on a deux filtres, le
premier reçoit un flux de caractères en entrée et le transmet en sortie au second.
Canal 1
Filtre 1
Canal 2
Filtre 2
Canal 3
Figure 1 : Exemple de Filtre et Canal
Ce style facilite la compréhension du comportement d’un système vu qu’il le décompose en un
ensemble de comportements spécifiés par les filtres. Ainsi, un système conforme à ce style est facile à
maintenir (ajouter un nouveau filtre, remplacer un filtre). Ce style favorise aussi la réutilisation puisqu’un
même filtre peut interagir avec plusieurs autres filtres via différents canaux lorsque les données échangées
sont compatibles. De plus, de par son organisation, ce style supporte l’exécution concurrente (les filtres
peuvent correspondre à des tâches séparées s’exécutant en parallèle au besoin) et permet l’analyse des sorties
et des analyses d’inter-blocage. Cependant, l’application de ce style peut dégénérer et donner une
décomposition purement séquentielle d’un système ce qui n’est pas adapté à certains types d’application (ex
: applications interactives).
3.
Les langages de description d’architecture (ADLs)
Un ADL fournit une syntaxe et une sémantique formelle pour modéliser l’architecture conceptuelle
d’un système. Il permet de spécifier abstraitement les éléments d’une architecture sans définir leur
implémentation. La majorité des ADLs partagent un ensemble des concepts essentiels à la modélisation
architecturale tels que les composants, les connecteurs et les configurations (Medvidovic et Taylor, 2000). Ils
visent généralement à spécifier explicitement les composants et la configuration d’un système. Cependant,
chaque ADL s’intéresse à une famille d’architecture particulière ou à un domaine donné, et de ce fait il
représente une approche particulière de spécification. Un ADL se concentre sur des aspects spécifiques de
l’architecture et privilégie des techniques puissantes mais spécifiques d’analyse. Avant de présenter en détail
les ADLs les plus communs, nous allons introduire les concepts sous-jacents à la description architecturale et
qui doivent être modélisés par un ADL.
LATECE Technical Report, October 2006
Page 5
3.1
Concepts de base
Les concepts de base qui forment une description architecturale sont le composant, le connecteur et
la configuration. Un ADL doit permettre la modélisation de ces concepts en plus de d’autres propriétés. En
se basant sur les études faites sur les ADLs (Clements, 1996) (Medvidovic et Taylor, 2000) (Shaw et Garlan,
1994) (Vestal, 1993), nous présentons, brièvement, les propriétés principales qu’un ADL doit avoir. Nous
divisons l’ensemble de ces propriétés en trois sous-familles : (1) les exigences minimales fondamentales que
tout ADL doit supporter ; (2) les exigences souhaitables dont le support permet des implémentations
correctes des architectures ; (3) les exigences désirables mais non fondamentales dont le support aide
grandement à la conception architecturale.
3.1.1
Les exigences minimales fondamentales
Spécification des composants : «Un composant est une unité de calcul localisée et indépendante.»
(Allen, 1997). C’est une unité de calcul ou de données qui peut être atomique ou composite et qui possède
une interface décrivant les points d’interaction du composant avec l’environnement. Un ADL doit permettre
la spécification d’un type de composant et de son interface.
Spécification des connecteurs : Le connecteur modélise les interactions entre les composants et
aussi les règles qui régissent ces interactions. Il peut être implanté sous forme d’appel de procédure, de
variable partagée, de canal, etc. Un connecteur a les mêmes caractéristiques qu’un composant (Medvidovic
et Taylor, 2000). Il a une interface qui regroupe l’ensemble des points d’interaction entre le connecteur et les
composants ou connecteurs qu’il relie. Il possède aussi un type qui représente une description abstraite de
l’interaction qu’il représente. Il est important qu’un ADL permette de spécifier un connecteur comme une
entité de première classe. Cela permet d’associer une interface à un connecteur et aussi de le réutiliser.
Spécification des configurations : La configuration architecturale, appelée aussi topologie, décrit la
structure complète d’un système. Elle se présente souvent sous forme de graphe connexe regroupant des
composants et des connecteurs. Un ADL doit fournir un support adéquat pour modéliser la configuration.
Spécification des styles architecturaux : Une architecture est conforme à un style si ses composants
et connecteurs sont ceux définis par le style en question et si toutes les configurations qu’elle comporte sont
conformes aux contraintes définies par le style. Il est important de pouvoir spécifier explicitement un style
architectural pour pouvoir faire un certain nombre d’analyses et de vérifications sur l’architecture d’un
système.
LATECE Technical Report, October 2006
Page 6
3.1.2
Les exigences souhaitables :
Modélisation de la sémantique : La sémantique des composants et des connecteurs est décrite par
des modèles de comportement. Le comportement d’un composant inclut l’aspect dynamique du composant
alors que celle du connecteur comprend la spécification des protocoles d’interaction qu’il décrit (Medvidovic
et Taylor, 2000).
Spécification des contraintes : Les contraintes sur un composant ou un connecteur représentent
l’ensemble des propriétés qu’il doit avoir et qui ne peuvent être violées. Les contraintes sur une
configuration architecturale sont des contraintes globales qui découlent souvent des contraintes sur les
composants et les connecteurs participant à la configuration.
Composition hiérarchique : Une architecture peut être décrite à différents niveaux d’abstraction. Un
composant ou un connecteur peut être lui-même un ensemble de composants et connecteurs. Une
architecture entière peut être représentée par un composant.
Propriétés non fonctionnelles : Les propriétés non fonctionnelles (ex : sécurité, performance,etc.)
représentent des exigences qui ne découlent pas directement de la sémantique des concepts architecturaux
(composant, connecteur, configuration). Toutefois, leur description est nécessaire pour une implémentation
correcte de ces concepts et aussi pour faire des vérifications, analyses et simulations de comportement en
cours d’exécution.
3.1.3
Les exigences désirables mais non fondamentales :
Support de la réutilisation : Il est désirable de pouvoir réutiliser des composants et des connecteurs
aussi bien que des configurations et des descriptions de styles dans la description de différents systèmes.
Aussi la modélisation des composants et des connecteurs par des types paramétrables favorise leur
réutilisation (Medvidovic et Taylor, 2000).
Évolution : Un composant, un connecteur et même un système sont amenés à évoluer
continuellement. Cette évolution se traduit par le changement de leurs propriétés. Ce changement de
propriétés est un aspect clé que les ADLs doivent supporter.
Support d’outil : La disponibilité d’un outil renforce l’utilité d’un ADL. En effet, le support d’outil
peut faciliter la conception architecturale d’un système ainsi que l’évaluation de ses propriétés. L’outil peut
même aller jusqu’à la génération d’un système exécutable à partir de la description architecturale.
LATECE Technical Report, October 2006
Page 7
4.
Survol des ADLs
Les ADLs couvrent différents domaines et se concentrent donc sur des concepts et aspects différents
de la description architecturale. Darwin se concentre sur la construction de systèmes distribués. Le langage
RAPIDE se concentre sur la spécification et l’analyse de l’aspect dynamique dans les architectures. Aesop
supporte l’utilisation des styles architecturaux et vise principalement à fournir une plate forme de
développement basée sur les styles. ACME, pour sa part, représente plus un langage unificateur pour
l’ensemble des ADLs. Il a pour but de permettre l’échange de descriptions architecturales exprimées par
différents ADLs. Le langage C2 supporte la description des systèmes distribués dynamiques, en particulier
les systèmes d’interface utilisateur. UniCon permet la composition et la vérification des systèmes à partir
d’éléments prédéfins. Le langage Wright se concentre plus sur la modélisation de tous les éléments
architecturaux (composant, connecteur, configuration et style) et sur les analyses statiques, en particulier, les
analyses des inter-blocages dans les systèmes concurrents.
En étudiant ces différents langages, nous avons pu identifier deux grandes familles d’ADLs. La
première famille d’ADLs se concentre sur la spécification explicite des propriétés architecturales
structurelles en particulier ces ADLs spécifient les connecteurs comme des entités de première classe. Cette
famille comprend les langages Wright, ACME, Aesop, C2 et UniCon. La seconde famille se concentre plutôt
sur la spécification de l’aspect dynamique des architectures et ne spécifie pas de façon explicite les
connecteurs. Cette famille inclut les langages Darwin et RAPIDE. Les ADLs que nous avons étudiés peuvent
aussi être classés selon leur « généricité ». En effet, contrairement aux autres ADLs, ACME et Aesop visent
à fournir un modèle architectural générique.
4.1
Les ADLs se concentrant sur l’aspect structurel
4.1.1
Wright
Le langage Wright a été développé à l’université Carnegie Mellon en 1997 (Allen, 1997)(Allen et
Garlan, 1997). Il décrit les composants et les connecteurs comme des éléments de première classe d’une
architecture. « Il fournit une base formelle pour la description des configurations et des styles
architecturaux » (Allen, 1997). En effet, il utilise une notation basée sur CSP (Hoare, 1985) pour décrire le
comportement et les interactions, ce qui permet de définir une sémantique formelle et de rendre possible un
certain nombre d’analyse et de vérification.
LATECE Technical Report, October 2006
Page 8
Wright fournit une spécification explicite pour le composant, le connecteur, la configuration et
même le style. Un composant est décrit en deux parties. Une partie qui contient la déclaration d’un ensemble
de ports qui représentent son interface et une partie qui représente la description du comportement du
composant appelée calcul (computation). Chaque port représente un point d’interaction entre le composant et
son environnement. Une spécification formelle exprimée par le langage CSP est associée à chaque port, elle
exprime les propriétés et les attentes du composant vu à travers ce port et elle constitue une partie de son
comportement. La spécification du calcul (computation) fournit une description complète du comportement
et des propriétés du composant en montrant comment les ports sont regroupés et utilisés. Les analyses faites
sur le composant se baseront sur cette spécification.
Dans une architecture Filtre et Canal (pipe and filter), considérons un exemple où on a deux filtres
(Filtre1, Filtre2), le premier reçoit un flux de caractères en entrée et le transmet en sortie au second filtre.
Filtre1
Filtre2
Figure 2. exemple de filtre et canal
Le filtre correspond à un composant qu’on peut décrire simplement avec le langage Wright comme
suit :
Component Filtre
Port Entrée [Lire les données jusqu’à ce que la fin des données soit atteinte]
Port Sortie [sortir les données de manière permanente]
Computation [Lire continuellement les données à partir du port Entrée, puis les envoyer sur le port Sortie]
Les ports « Entrée » et « Sortie » forment l’interface du composant « Filtre ». Les spécifications des
deux ports et de la partie calcul sont normalement exprimées avec le langage CSP.
Le langage Wright définit explicitement un type de connecteur. Ce type correspond, en fait, à un
patron d’interaction qui peut être utilisé par plusieurs instances de connecteur. Un connecteur permet ainsi de
structurer la façon dont un composant interagit avec le reste du système et de fournir des exigences
auxquelles un composant doit se conformer. De la même façon qu’un composant est défini, un type de
connecteur est décrit en deux parties. Une partie qui définit un ensemble de rôles et une partie qui représente
la spécification d’assemblage (glue). Chaque rôle correspond à une partie intervenante dans l’interaction et
sa spécification, exprimée en CSP, décrit le comportement attendu de cet intervenant. La spécification
d’assemblage, quat à elle, décrit comment les activités des rôles sont coordonnées. En fait, elle spécifie
LATECE Technical Report, October 2006
Page 9
comment les calculs (computation) des différents participants (composants) sont combinés pour former un
calcul plus large et qui correspond au comportement global et complet du connecteur.
Dans l’exemple précédent, le canal a deux rôles (source et récepteur), la partie « Glue » décrit
comment les données sont délivrées du rôle Source au rôle Récepteur. La description avec Wright est
comme suit :
Connector Canal
Role Source [produire continuellement les données, signaler la fin par une fermeture]
Role Récepteur [Lire continuellement les données, fermer à la fin ou avant la fin des données]
Glue [ Récepteur reçoit les données dans le même ordre qu’elles sont produites par Source]
Pour chaque rôle déclaré dans la spécification du connecteur ainsi que pour la partie assemblage
(Glue), on fournit une description en CSP. L’exemple suivant montre la spécification détaillée d’un
connecteur entre les composants Client et Serveur.
Le rôle du serveur est décrit par un processus continue qui accepte une invocation et envoie un retour
ou qui se termine avec succès (le processus noté § représente un processus qui se termine avec succès). Le
rôle du client est décrit de façon similaire par un processus continue qui appelle un service et reçoit le
résultat ou se termine avec succès. La différence majeure dans la spécification des deux rôles est le choix de
l’opérateur (interne Π ou externe
) qui permet de distinguer formellement entre une situation où le
comportement d’un processus est dicté par l’environnement (ici le serveur est obligé de fournir un service
lorsqu’il y a une requête), et la situation ou un rôle peut choisir d’utiliser des services mais il n y est pas
obligé (c’est le cas du client qui peut émettre une requête ou pas). Le processus d’assemblage « glue »
coordonne le comportement des deux rôles en indiquant comment les événements de chaque rôle
interagissent ensemble.
LATECE Technical Report, October 2006
Page 10
Une configuration représente la description de l’architecture complète d’un système. Elle regroupe
des instances de composants reliés via des instances de connecteurs. L’architecture est composée de trois
parties. La première partie définit les types de connecteurs et de composants. La deuxième partie spécifie un
ensemble d’instances de composants et connecteurs. Plusieurs instances du même type de composant ou
connecteur peuvent exister dans la même configuration. Pour cela chaque instance est nommé d’une façon
explicite et unique. Dans la troisième partie de la description, les instances de composants et connecteurs
sont combinées en précisant quels ports (d’un composant) sont attachés à quels rôles (de connecteur). Cette
partie décrit, donc, la topologie de la configuration. La configuration correspondante à notre exemple a cette
forme :
Configuration Filtre-Canal
Component Filtre
Connector Canal
Instances
Filtre1, Filtre2 : Filtre
C1 : Canal
Attachments
Filtre1.Sortie as C1.Source
Filtre2.Entrée as C1.Récepteur
End Filtre-Canal.
Les ports et les rôles associés dans la troisième partie « Attachments » doivent être compatibles. Cela
signifie que le port est conforme aux règles imposées par le rôle pour pouvoir participer à l’interaction
spécifiée par le connecteur. Les spécifications des ports et des rôles sont nécessaires pour la vérification de la
compatibilité.
Le langage Wright permet la composition hiérarchique. En fait, la partie calcul (computation) d’un
composant peut être représentée par une configuration correspondant au sous-système architectural que le
composant représente. De la même façon la partie glue d’un connecteur peut être exprimée sous forme de
configuration. WRIGHT permet aussi la spécification d’un vocabulaire par la définition des types de
composant et connecteur. Il utilise les types d’interfaces pour spécifier les contraintes sur une partie d’un
composant (port) ou un connecteur (rôle). Par exemple le style Filtre-Canal peut définir deux types
d’interfaces (EntréeDonnée et SortieDonnée) pouvant être utilisées par un Filtre. En plus, pour pouvoir
réutiliser les mêmes descriptions, Wright permet de paramétrer les types. En effet, on peut remplacer par une
variable la description d’un port ou d’un rôle, un calcul ou le nom d’une interface. La variable sera substituée
par un paramètre au moment où le type concerné est instancié.
LATECE Technical Report, October 2006
Page 11
Pour qu’un système soit conforme à un style, il doit en plus de se conformer au vocabulaire du style,
contenir des configurations qui obéissent toutes aux contraintes et propriétés intrinsèques au style. Pour ce
faire, WRIGHT utilise des prédicats logiques de premier ordre pour exprimer ces contraintes. Par exemple,
les connecteurs dans l’architecture Filtre-Canal (pipe-filter) doivent être tous de type Canal. Cela est exprimé
en WRIGHT avec le prédicat : ∀ c : Connectors . Type (c) = Canal. La spécification d’une partie du style
Filtre-Canal est exprimée avec WRIGHT comme suit :
Style Filtre-Canal
Component Filtre
Connector Canal
Interface Type EntréeDonnée = [Lire continuellement les données, fermer le port à la fin ou avant
la fin des données]
Interface Type SortieDonnée = [produire continuellement les données, fermer le port pour
signaler la fin des données]
Constraints
∀ c : Connectors . Type (c) = Pipe
Λ ∀ c : Component ; p :Port | p∈ Ports(c ) . Type(p)= EntréeDonnée v Type(p) = SortieDonnée
[etc..]
endStyle
Wright permet aussi l’extension des styles en définissant des sous-styles. Un sous-style est soumis à
toutes les contraintes de son « super-style » et inclut tout son vocabulaire.
Pour conclure, l’une des caractéristiques essentielles de WRIGHT est qu’il modélise d’une façon
explicite un connecteur. Cela permet la séparation des deux concepts composant et connecteur et de
promouvoir, ainsi, la réutilisation des deux. Aussi, l’utilisation du langage CSP pour exprimer les
comportements et les interactions, permet à WRIGHT de spécifier les éléments architecturaux d’une façon
précise et abstraite. L’utilisation des prédicats pour spécifier le style architectural, permet aussi un certain
nombre de vérifications comme la cohérence de l’interface d’un composant avec le connecteur auquel il est
attaché, la cohérence interne d’un connecteur et la complétude d’une configuration. Cependant, l’utilisation
d’un langage comme CSP rend l’utilisation et l’assimilation de WRIGHT assez difficile. En plus, WRIGHT
ne dispose pas d’un outil pour permettre d’aller de la spécification abstraite jusqu’à l’implémentation et la
génération de code. Il s’est plus concentré sur l’analyse statique et plus précisément les analyses des interblocages. Un autre inconvénient de WRIGHT est qu’il ne supporte pas la modélisation des propriétés non
fonctionnelles.
LATECE Technical Report, October 2006
Page 12
4.1.2
ACME
ACME (Garlan et al., 1997) (Garlan et al., 2000), développé à l’université Carnegie Mellon,
représente une base commune aux langages de description d’architecture. Il a pour but de permettre
l’échange de spécifications architecturales entre différents ADLs. ACME se base sur sept types d’entités
pour décrire une architecture : les composants, les connecteurs, les systèmes, les ports, les rôles, les
représentations et les rep-maps (representation map). Un composant correspond, comme dans WRIGHT, à
une unité de calcul par exemple : un client, un serveur, un filtre, etc. Les ports représentent les points
d’interaction du composant avec son environnement. Un connecteur représente des interactions entre
composants et a aussi une interface composée de rôles. Chaque rôle correspond à un participant à
l’interaction.
La fig.3 représente un diagramme correspondant à une architecture client-serveur. Ce système
contient deux composants : le client et le serveur. Ces composants sont reliés par le connecteur RPC.
figure 3. architecture client-serveur
Ce système est décrit avec ACME comme suit :
System simple_cs = {
Component client = { Port send-request }
Component server = { Port receive-request }
Connector rpc = { Roles {caller, callee} }
Attachments : {
client.send-request to rpc.caller ;
server.receive-request to rpc.callee }
}
ACME permet la composition hiérarchique. En effet, un composant ou un connecteur peut avoir
plusieurs descriptions de niveau plus bas. Ces descriptions sont appelées représentations. Les « rep-maps »,
quant à elles, établissent la correspondance entre l’interface externe d’un composant ou connecteur et ses
représentations. Dans un cas simple de composant représentant un sous-système, une rep-map fait
l’association entre les ports du composant et les ports des composants appartenant à ce sous-système.
Pour spécifier des informations additionnelles relatives au domaine ou au comportement, chacune de
ces sept entités qu’on vient de définir, peut être annotée avec des listes de propriétés. Une propriété est
LATECE Technical Report, October 2006
Page 13
caractérisée par son nom, son type et sa valeur. Le type peut être simple : entier, caractère ou booléen, il peut
indiquer un « sous-langage » avec lequel la propriété est spécifiée, comme il peut être « external » pointant
sur un lien externe.
figure 4. représentations et propriétés d’un composant
L’exemple du client-serveur, intégrant des propriétés, est décrit comme suit :
System simple_cs = {
Component client = {
Port send-request;
Properties {Aesop-style : style-id = client-server;
UniCon-style : style-id = cs;
source-code : external = "CODE-LIB/client.c" }}
Component server = {
Port receive-request;
Properties { idempotence : boolean = true;
max-concurrent-clients : integer = 1;
source-code : external = "CODE-LIB/server.c" }}
Connector rpc = {
Roles {caller, callee}
Properties { synchronous : boolean = true;
max-roles : integer = 2;
protocol : Wright = "..." }}
Attachments {
client.send-request to rpc.caller ;
server.receive-request to rpc.callee }
}
ACME a aussi introduit la notion de gabarit « template » pour définir des structures syntaxiques
paramétrées que l’on peut instancier plusieurs fois. Les gabarits appartenant à la même famille de systèmes,
LATECE Technical Report, October 2006
Page 14
sont regroupés pour définir un style architectural. Le style client-serveur, par exemple, inclura des gabarits
pour définir le client, le serveur et le connecteur RPC. Il est décrit comme suit :
Style client-server = {
Component Template client(rpc-call-ports : Ports) = {
Ports rpc-call-ports;
Properties { Aesop-style : style-id = client-server;
Unicon-style : style-id = cs;
source-code : external = "CODE-LIB/client.c" }}
Component Template server(rpc-receive-ports : Ports) = {
Ports rpc-receive-ports;
Properties { Aesop-style : style-id = client-server;
Unicon-style : style-id = cs;
component-class : type = server;
source-code : external = "CODE-LIB/server.c" }}
Template rpc(caller_port, callee_port : Port) defining (conn : Connector) =
{ conn = Connector {
Roles {caller, callee}
Properties { synchronous : boolean = true;
max-roles : integer = 2;
protocol : Wright = "..." }}
Attachments { conn.caller to caller_port;
conn.callee to callee_port; }}
}
Un exemple d’instance de ce style se présente comme suit :
System complex_cs : client-server = {
c1 = client(send-request);
c2 = client(send-request);
c3 = client(send-request);
s1 = server(receive-request);
s2 = server(receive-request);
rpc(c1.send-request, s1.receive-request);
rpc(c2.send-request, s1.receive-request);
rpc(c3.send-request, s2.receive-request);
}
ACME se concentre plus sur la spécification de la structure d’une architecture que sur l’aspect
sémantique. Il se base sur un cadre sémantique ouvert (open semantic framework) de spécification. « Ce
cadre fournit la sémantique structurelle de base tout en permettant à des ADLs spécifiques de définir le
comportement des architectures en utilisant la construction : propriété ». Il permet la spécification dans une
logique formelle des aspects structurels du langage. Cette spécification est appelée prescription.
LATECE Technical Report, October 2006
Page 15
Un exemple de prescription concernant l’exemple du client-serveur et exprimant un certain nombre
de relations et contraintes, est comme suit :
exists client, server, rpc |
component(client) ^
component(server) ^
connector(rpc) ^
attached(client.send-request,rpc.caller) ^
attached(server.receive-request,rpc.callee) ^
client != server ^
server != rpc ^
client != rpc ^
(for all y:component (y) => y = client | y = server) ^
(for all y:connector(y) => y = rpc) ^
(for all p,q: attached(p,q) => (p=client.send-request ^ q=rpc.caller) | (p=server.receive-request ^ q=rpc.callee))
Pour illustrer comment ACME peut jouer un rôle d’intégrateur entre différents ADLs, (Garlan et al.,
1997) ont effectué une opération de traduction d’une description écrite avec le langage WRIGHT au langage
RAPIDE. La traduction se fait en trois étapes comme on peut le voir sur la figure 5.
figure 5. Traduction de WRIGHT vers RAPIDE par l’intermédiaire d’ACME
La première et la troisième étape sont faciles à réaliser. En effet, la correspondance entre les
structures architecturales de WRIGHT et ACME se fait facilement, les spécifications comportementales sont
aussi traduites en annotations. De la même façon, les descriptions ACME, annotées avec des spécifications
du langage RAPIDE, sont traduites facilement en descriptions RAPIDE. L’étape intermédiaire est la plus
difficile, elle consiste à traduire une annotation exprimée en WRIGHT en une annotation exprimée en
RAPIDE. Cette difficulté est dû principalement au fait que le connecteur n’est pas une entité de première
classe dans le langage RAPIDE. (Garlan et al., 1997) ont choisi de traduire tous les connecteurs non triviaux
dans WRIGHT en composants dans RAPIDE et d’utiliser de simples connecteurs sous forme d’événements
associés pour lier les composants.
LATECE Technical Report, October 2006
Page 16
Pour conclure, ACME est plus un médiateur entre ADLs qu’un ADL. Il permet à n’importe quel
outil qui supporte les sept concepts de base d’interagir avec d’autres outils. En fait, ACME fournit des bases
simples qui forment un point de départ pour le développement de nouveaux ADLs. De plus, l’utilisation des
« Templates » et des styles permet d’encapsuler des patrons réutilisables. Des ADLs peuvent même être
construits en choisissant simplement un ensemble de « Templates » ou styles déjà définis. Cependant,
ACME ne permet pas la spécification directe de la sémantique ni des propriétés non fonctionnelles, il permet
de spécifier des annotations exprimées dans différents ADLs, mais ces annotations sont non interprétables
par l’outil accompagnant ACME lui-même. Cet outil ne permet pas non plus le raffinement du modèle
architectural et donc on ne peut pas aller jusqu’à la génération de code. La dynamique du système, elle non
plus, n’est pas prise en charge par ACME, ce qui limite les analyses possibles à des analyses syntaxiques.
Finalement, l’utilisation de ACME comme un langage d’intégration entre différents ADLs, est dépendante
de l’existence d’outils « traducteurs » entre lui et ces ADLs.
4.1.3
UniCon
UniCon (Language for Universal Connector support) (Shaw et al., 1995) (Zelesnik, 1996) se base
sur deux types de constructions : Composant et Connecteur. Ces deux concepts ont les mêmes propriétés à
l'exception que les connecteurs ne sont pas composites alors que les composants peuvent l'être. Un
composant ou un connecteur a les caractéristiques suivantes : un nom, une spécification (appelée Interface
pour un composant et Protocole pour un connecteur), un type, un ensemble de propriétés sous forme de liste
de propriétés (attributs et leurs valeurs associées), un ensemble de points d'association (appelés Players pour
les composants et Rôles pour les connecteurs), et une implantation. Les attributs dans la liste de propriétés
associée à un composant fournissent une spécification plus détaillée du composant et le contraignent.
L'implantation d’un composant peut être composite ou non. Son interface doit être compatible avec
son implantation. Si l'implantation est composite, l'interface doit être compatible avec les interfaces de ses
composants et avec les protocoles de ses connecteurs. L'interface fournit des garanties de comportement et
de performances du composant. Elle doit inclure : le type du composant, des déclarations et des contraintes
sur le composant et les players définis par le composant. Les players sont les unités sémantiques visibles à
travers lesquelles un composant interagit. Chaque player a un nom, un type et des attributs optionnels
(signature, spécifications fonctionnelles, contraintes, etc.). De façon analogue aux composants, les
spécifications détaillées des players ont la forme de listes de propriétés.
Pour illustrer, l’exemple d’un système Pipe-and-Filter (du style Unix) est utilisé. Ce système (Fig.6)
implante un indexeur KWIC (Keyword in context). Cet exemple inclut 4 filtres (caps, shifter, merge, sorter),
LATECE Technical Report, October 2006
Page 17
un fichier (req-data), 4 canaux et 2 streams qui sont les players du système entier qui est lui même un filtre.
3 des filtres ont une interface simple (stdin, stdout et stderr), le filtre merge a, par contre, deux entrées.
Figure 6. Le système indexeur KWIC
La figure 7 montre la spécification textuelle de deux composants du système KWIC. Le composant
sort est un composant simple alors le composant KWIC représente un composant composite correspondant
au système entier. Un système est considéré dans UniCon comme un composant composite.
UniCon limite les types des composants à un ensemble prédéfini (énumération). Pour chaque type de
composant, il y a aussi des types prédéfins de players qui sont permis. La table suivante montre les types
supportés de composants et les types de players associés.
Remarque : Le type General permet tout type de player, permettant ainsi la définition de
composants arbitraires, mais il ne supporte ni analyses ni vérifications.
LATECE Technical Report, October 2006
Page 18
Figure 7. Spécification d’un composant primitif et d’un composant composite avec UniCon
Les composants primitifs sont implémentés directement dans du code avec un langage de
programmation ou comme données stockées dans des fichiers. UniCon permet plusieurs représentations d’un
même composant. L’attribut Variant permet de choisir la représentation désirée lors de l’instanciation d’un
LATECE Technical Report, October 2006
Page 19
composant. Pour sa part, l’implantation d’un composant composite doit fournir 3 types d’information : (1)
les parties participantes : instanciation de composants et de connecteurs contenus dans le composant ; (2) la
configuration : description de la façon dont les instances de connecteurs relient celles des
composants (associations entre players et rôles); (3) l’abstraction : spécification de la façon dont les players
de l’interface du composant global sont associés avec les players de l’implantation. Les players de cette
interface sont appelés ExternalPlayers car ce sont les players que le composant doit fournir. Dans
l’implantation, les players sont fournis lorsque les composants sont instanciés, ce sont des InternalPlayers.
L’étape d’abstraction définit donc les ExternalPlayers en terme de InternalPlayers.
L’implantation du composant KWIC (fig.7) est composite. Elle définit d’abord les parties à utiliser
(composants et connecteurs). Ensuite, elle associe l’entrée du premier filtre (caps) à l’entrée de l’interface de
KWIC et elle associe la sortie du dernier filtre (sorter) à la sortie de l’interface de KWIC. Ceci est un cas
simple où les ExternalPlayers sont associés aux InternalPlayers du même type. Dans certains cas,
l’association peut ne pas être directe. Finalement, l’implantation de KWIC définit la configuration du
système en indiquant quelles entrées et sorties sont reliées et avec quels canaux. L’exemple de la fig.7
montre deux façons de faire cela : (1) en associant individuellement les players aux rôles des canaux déjà
instanciés ; (2) par une seule instruction qui instancie implicitement le canal et fait toutes les connexions en
même temps.
Un connecteur spécifie un protocole et une implantation. Le protocole décrit une classe
d’interactions que le connecteur fournit. Un protocole définit des rôles correspondants aux responsabilités
des parties participantes lesquelles définissent des exigences sur les players des composants pouvant
participer à l’interaction décrite par le protocole. Le protocole doit inclure : le type du connecteur, les
assertions qui contraignent le connecteur entier, et les rôles qui participent au protocole. Les rôles sont les
unités sémantiques visibles à travers lesquelles un connecteur réalise l’interaction entre les composants. Un
rôle doit spécifier un nom, un type et il peut spécifier optionnellement d’autres attributs. Les spécifications
détaillées des rôles ont la forme de listes de propriétés. La fig.8 montre la définition d’un connecteur canal
(pipe) du système KWIC. La spécification détaillée de chaque connecteur est réalisée par une liste de
propriétés (associations attributs/valeurs). Il est à noter que l’implantation d’un connecteur est définie et
générée par UniCon (BUILTIN).
LATECE Technical Report, October 2006
Page 20
Figure 8. Un exemple de connecteur
Seuls les implantations primitives des connecteurs sont supportées. Les types des connecteurs et les
types des rôles font partie d’un ensemble prédéfini de types. Les types sont décrits dans la table suivante :
UniCon offre une notation graphique pour construire les spécifications de façon incrémentale. La
figure 6, par exemple, a été générée par l’interface graphique mais les annotations ont été ajoutées
manuellement. L’éditeur graphique d’UniCon invoque des mécanismes de contrôle pour vérifier autant que
possible le diagramme lors de son développement de façon à prévenir les erreurs au lieu de les corriger après
développement. Lorsqu’une composition graphique est complétée, l’outil génère une représentation textuelle
LATECE Technical Report, October 2006
Page 21
du composant. L’implantation de UniCon offre aussi des facilités pour invoquer un outil d’analyses (RMA :
rate monotonic analysis) qui permet des analyses de planification en temps réel.
Pour conclure, UniCon spécifie de façon explicite les connecteurs. Il permet de construire de façon
incrémentale un système tout en effectuant une validation de la composition réalisée. Enfin, le langage est
doté d’un environnement contenant un éditeur graphique, un analyseur syntaxique et un générateur de code
en langage C. Cependant, UniCon se concentre sur les aspects structurels d’une architecture, l’aspect
dynamique n’est pas pris en compte. De plus, les types des composants et des connecteurs font partie d’un
ensemble prédéfini de types. Aussi, un connecteur ne peut pas être composite et en plus il n’est pas possible
de lui associer une implantation autre que celle créée par UniCon. UniCon ne fournit pas de construction
pour spécifier un style architectural. De plus, Il ne se base sur aucune notation formelle pour spécifier la
sémantique des composants et connecteurs mais plutôt sur une liste d’attributs et n’offre pas de support pour
la spécification des propriétés fonctionnelles.
4.1.4
Aesop
Aesop (Garlan et al., 1994) (Garlan, 1995) a été développé dans le but de générer à un moindre coût
des environnements de développement spécifiques à des styles architecturaux et cela en spécialisant un
modèle architectural générique. En effet, en termes des propriétés d’un style, le vocabulaire de conception
d’Aesop est générique (composant, connecteur, etc.), les configurations ne sont pas contraintes, il n’y a pas
d’interprétation sémantique et les analyses sont limités à la vérification de propriétés topologiques. Les outils
associés à Aesop incluent un éditeur graphique et un éditeur de texte pour les annotations.
La description architecturale dans Aesop est basée sur une ontologie générique de 7 entités (Figure
9) : composants, connecteurs, configurations, ports, rôles, représentations et associations (bindings). Les
composants et les connecteurs ont des interfaces. L’interface d’un composant est défini par un ensemble de
ports qui déterminent les points d’interaction du composant avec son environnement. L’interface d’un
connecteur est définie par un ensemble de rôles qui identifient les participants dans l’interaction. De façon
analogue à ACME, Aesop utilise une représentation pour décrire le « contenu » (ex : fichier, code, etc.) ou la
configuration interne d’un composant ou d’un connecteur (dans le cas où ils sont composites). Les bindings
permettent de faire la correspondance entre les éléments de la configuration interne et l’interface externe
d’un composant ou d’un connecteur. Un binding (Figure 9) identifie un port interne (resp. rôle interne) à un
port externe (resp. rôle externe).
LATECE Technical Report, October 2006
Page 22
Figure 9. Éléments génériques d’une description architecturale
Dans Aesop, chacun de ces 7 concepts est représenté par une classe C++. Les opérations supportées
par ces classes incluent l’ajout et la suppression de ports à des composants, la connexion d’un rôle à un port,
l’établissement d’une correspondance (binding) entre deux ports ou deux rôles, l’ajout d’une nouvelle
représentation à un port ou un connecteur, etc. Souvent, la représentation d’un composant ou d’un
connecteur n’est pas architecturale (ex : code source). Cette représentation est mieux manipulée par des
outils externes non architecturaux (ex : compilateur). Pour traiter ces données externes, Aesop fournit un
sous-type de la représentation appelée External_Rep (Fig.10).
Figure 10. Définition des styles par sous-typage
Les interfaces définies par Aesop sont intentionnellement minimales. Le but est de fournir un cadre
minimal pour la description architecturale permettant de spécifier des informations additionnelles comme des
élaborations stylistiques. Pour définir un style Aesop utilise le sous-typage : un vocabulaire spécifique à un
style est spécifié par des sous-types des classes architecturales de base ou de leurs sous-types. Les
contraintes du style sont alors supportées par les méthodes de ces types. De plus, un style peut identifier des
outils externes (ex : outil d’analyses, outil de développement). Cependant, les sous-classes du style doivent
respecter la comportement sémantique de leurs super-classes : une sous-classe doit fournir un comportement
LATECE Technical Report, October 2006
Page 23
strict de sous-typage pour les opérations mais elles peuvent introduire des sources additionnelles d’échec
(ex : l’opération d’ajout d’un port à un composant doit être supportée par le style pipe-filter, mais dans le cas
du filtre on ne permet l’ajout d’un port que s’il est une instance d’un type de ports défini par le style : port
d’entrée ou port de sortie). La figure 10 montre la hiérarchie des types utilisée pour définir les style pipefilter et pipeline (pipeline est défini comme un sous-type de pipe-filter).
Aesop fournit une interface par défaut sous la forme d’un éditeur graphique. Pour générer un
environnement spécifique à un style, cet éditeur doit aussi être spécialisé. Pour ce faire, chaque classe
architecturale est associée à une ou plusieurs classes de visualisation. Les nouvelles classes introduites par un
style héritent des visualisations de leurs super-classes mais peuvent définir leurs propres classes de
visualisation.
L’avantage de Aesop est qu’il permet de définir plusieurs styles architecturaux. Son modèle
architectural générique définit explicitement tous les concepts de base (composant, connecteur et
configuration). Aussi, il permet d’intégrer d’autres environnements de développement et des outils externes.
Cependant, les contraintes et invariants d’un style ne sont pas spécifiés de façon explicite et claire. Ils sont
encodés de façon impérative dans les méthodes des types associés au style. De plus, l’aspect dynamique et
les propriétés fonctionnelles des architectures ne sont pas supportés.
4.1.5
C2
C2 (Taylor et al., 1996) a été conçu pour supporter les besoins particuliers des applications possédant
des interfaces graphiques. Selon ces concepteurs C2 peut aussi supporter d’autres types d’applications. En
fait, C2 a été introduit comme un style architectural représenté par un réseau de composants reliés ensemble
par des dispositifs de transmission de messages. Les éléments clés du style C2 sont les composants et les
connecteurs. Une architecture est une configuration d’un ensemble de composants et de connecteurs. C2
spécifie aussi un ensemble de règles pour relier les composants et les connecteurs. Les composants
communiquent uniquement par passage de message et jamais à travers une mémoire partagée. Composants et
connecteurs possèdent deux interfaces («top» et «bottom»). Une interface «top» (resp. «bottom») d’un
composant peut être attachée au plus à une interface «bottom» (resp. «top») d’un connecteur. Par contre, un
connecteur peut être attaché à n’importe quel nombre de composants et de connecteurs. La responsabilité
d’un connecteur est le passage et la diffusion de messages. Il peut aussi appliquer des règles de filtrage et de
diffusion de messages (no filtering, notification filtering, prioritized et message sink).
LATECE Technical Report, October 2006
Page 24
Un composant peut avoir un état et ses propres tâches de contrôle. Son interface «top» définit
l’ensemble des notifications auxquelles le composant répond et l’ensemble des requêtes que le composant
émet vers le haut de l’architecture. En fait, les requêtes peuvent être envoyées seulement vers le haut de
l’architecture «upward» et les notifications vers le bas «downward». L’interface «bottom» d’un composant
définit l’ensemble des notifications qu’il émet vers le bas de l’architecture et l’ensemble des requêtes
auxquelles il répond. Un composant C2 (Figure 11) contient : (1) Un objet (internal object) avec une
interface définie, cet objet peut être complexe ; (2) Un encapsulateur de l’objet qui à chaque invocation à une
routine de l’interface de l’objet, transforme cette invocation et toutes les valeurs retournées en une
notification de l’interface «bottom» du composant et envoie cette notification au connecteur sous le
composant. Ainsi, les types de notifications émises par un composant sont déterminées par l’interface de son
objet interne. (3) Un gestionnaire de dialogues et contraintes qui est le seul à pouvoir invoquer les routines
d’accès d’un objet. La partie dialogue peut avoir sa propre tâche de contrôle et peut agir sur un objet en
réaction à une notification qu’elle a reçu d’un connecteur au dessus du composant ou pour exécuter une
requête reçue du connecteur au dessous du composant ou pour maintenir certaines contraintes définies dans
le dialogue. (4) Un traducteur de domaine qui aide à faire la correspondance entre le domaine de la
sémantique interne du composant et celui du connecteur au dessus du composant. En pratique, une
notification annonce des changements d’état de l’objet interne d’un composant alors qu’une requête est une
directive générée par la partie dialogue d’un composant demandant qu’une action soit réalisée par certains
composants qui sont au dessus du composant concerné.
Figure 11. L’architecture interne d’un composant C2
La syntaxe (en BNF) d’un composant en C2 se présente comme suit :
LATECE Technical Report, October 2006
Page 25
Un extrait de la syntaxe de l’interface montrant les deux types «top» et «bottom» se présente ainsi :
Pour illustrer, nous utilisons un exemple extrait de (Medvidovic et al., 2002). C’est une version
simplifiée d’un système d’ordonnancement de réunions. Dans ce système, un initiateur de réunion demande à
tous les participants l’ensemble des dates auxquelles ils ne peuvent être présents à la réunion (exclusion set)
et l’ensemble des dates auxquelles ils préfèrent que la réunion se tienne (preference set). Ces ensembles de
dates sont contenues dans un intervalle de temps imposé par l’initiateur (date range). La figure 12 montre
une vue graphique du style architectural C2 pour ce système qui contient des composants supportant les
fonctionnalités d’un initiateur (Meeting Initiator) et des participants (Attendees et ImportantAttendees). Trois
connecteurs sont utilisés pour l’échange de messages entre composants. Certains messages de l’initiateur
sont envoyés à tous les participants alors que d’autres sont destinés seulement aux participants importants.
C’est le connecteur «MainConn» qui s’assure que les connecteurs «AttConn» et «ImportantAttConn»
reçoivent seulement les messages destinés aux composants qui leur sont respectivement attachés.
LATECE Technical Report, October 2006
Page 26
Figure 12. Architecture du système d’ordonnancement de réunions
L’initiateur envoie des requêtes aux participants qui répondent par notification. Il essaye alors
d’organiser une réunion et la confirme aux participants (si elle peut être organisée). Sinon, il envoie d’autres
requêtes aux participants pour étendre l’intervalle de temps établi, ou ajouter des dates préférées ou
supprimer un ensemble de dates exclues ou se retirer de la réunion. L’initiateur communique avec les
participants à travers son interface « top ». Sa spécification en C2 se présente comme suit :
La partie startup incluse dans la partie behavior de l’initiateur spécifie les requêtes qu’il envoie
pour initier le processus. Les participants, quant à eux, communiquent avec les autres parties à travers leurs
interfaces «bottom».
LATECE Technical Report, October 2006
Page 27
Un participant important est une spécialisation d’un participant. Il a les mêmes fonctionnalités d’un
participant mais il ajoute une fonctionnalité qui est la spécification des préférences de lieu de réunion :
L’architecture entière du système est décrite comme suit :
LATECE Technical Report, October 2006
Page 28
Un système ayant 3 simples participants et 2 participants importants est instancié comme suit :
Finalement, C2 est doté d’un environnement (ARGO et DRADEL) permettant l’édition graphique
des modèles architecturaux, l’analyse de la syntaxe et la sémantique des modèles et la génération d’une
partie de l’implantation d’un système.
Parmi les avantages de C2 est qu’il assure une certaine indépendance du composant vis à vis de la
partie du système qui est en dessous de lui. L’association de tâches de contrôles (threads) aux composants
facilite la modélisation des systèmes concurrents ou distribués. C2 permet aussi la construction des
configurations à partir de composants hétérogènes. Cependant, il ne définit pas la sémantique des
connecteurs même s’il les spécifie de façon explicite. De plus, C2 ne permet pas de spécifier explicitement
un style architectural et ne supporte pas la spécification des propriétés fonctionnelles.
4.2
Les ADLs se concentrant sur l’aspect dynamique
4.2.1
Darwin
Darwin (Magee et al., 1995) a été conçu dans l’objectif de faciliter la conception de systèmes
distribués. C’est une notation pour spécifier la structure des systèmes composés à partir de différents
LATECE Technical Report, October 2006
Page 29
composants utilisant différents mécanismes d’interaction. Darwin offre aussi bien une représentation
textuelle que graphique des concepts architecturaux qu’il permet de spécifier. Les concepts utilisés dans
Darwin sont les composants et les services. Les services représentent les mécanismes par lesquels les
composants interagissent. Un composant est spécifié en Darwin par les services qu’il fournit pour permettre
à d’autres composants d’interagir avec lui et les services qu’il requiert pour interagir avec d’autres
composants. La figure 13 montre un exemple de composant qui est un filtre qui fournit (provides) un service
(output) et requiert (requires) un service (input). Le type de service est spécifié entre <>. Dans cet exemple,
le mécanisme de communication est un stream et le type de données communiquées est char. Un composant
peut fournir plusieurs services et en requérir plusieurs. Les noms des services sont locaux. En fait, un
composant n’a pas à connaître les noms globaux des services externes ni leur localisation dans le système
distribué. Cela permet d’implanter et tester un composant indépendamment du reste du système et aussi de le
réutiliser et le remplacer facilement.
Figure 13. Exemple d’un composant
Un composant composite est défini en déclarant les instances des composants (potentiellement
concurrents et distribués) qu’il contient et les liaisons (bindings) entre ces composants. Les bindings
associent les services requis par un composant aux services fournis par d’autres. La figure 14 montre un
composant pipeline composé d’une succession linéaire d’instances de filtres. Chaque entrée d’une instance
d’un filtre est liée à la sortie de l’instance qui la précède. Les liaisons sont déclarées par le mot clé bind. Les
services requis qui ne peuvent être satisfaits à l’intérieur du composant sont rendus visibles à un plus haut
niveau en les liant à un service requis de l’interface du composant composite, c’est le cas dans l’exemple du
service requis (input) du filtre F[0]. De la même façon, les services fournis qui sont requis en dehors du
composant composite sont liés à un service fournis par l’interface du composant composite, par exemple le
service fourni (output) par F[n-1]. Les outils accompagnant Darwin vérifient que les liaisons sont faites entre
services requis et services fournis ayant des types compatibles. Plusieurs services requis peuvent être reliés à
un seul service fourni. Aussi, un service peut transmettre ou recevoir l’information ou faire les deux.
LATECE Technical Report, October 2006
Page 30
Figure 14. Exemple d’un composant composite
Dans l’exemple de la figure 14, chaque instance de filtre F[k] est localisée dans une machine
différente moyennant l’annotation @k+1. Les entiers identifiant les machines sont associés aux adresses
réelles des machines par le système runtime de Darwin. Ce niveau d’indirection dans l’association permet
des spécifications portables.
Pour pouvoir spécifier la sémantique précise des composants, Darwin utilise le π-calculus (réf) qui
est un langage formel de processus visant à décrire et analyser les propriétés des processus concurrents et
mobiles. La déclaration d’un service fourni (provide p) est modélisé avec le π-calculus (Figure 15) par un
processus appelé agent Prov(p,s) qui est accédé par le nom p et qui gère le service s. Le service s est
simplement le nom ou la référence à un service implanté par un composant. Darwin ne se préoccupe pas de
la manière dont le service est implanté, il s’occupe de placer le service s là où il est requis. L’agent Prov
reçoit la localisation x où s est requis et envoie s à cette localisation. Comme le service peut être requis par
plusieurs composants, l’agent Prov est défini comme étant un processus répétitif (noté : !). La déclaration
d’un service requis (require r) est faite de façon similaire par un agent Req(r,l) (Figure 16). Req(r,l) reçoit le
nom d’accès (y) d’un agent Prov et lui envoie la localisation l où le service est requis. Finalement, le binding
est modélisé par un agent Bind(r,p) (Figure 17) qui envoie simplement le nom d’accès de l’agent Prov à
LATECE Technical Report, October 2006
Page 31
l’agent Req. La composition des agents Req, Bind et Prov (notée Req(r,l) | Bind(r,p) | Prov(p,s) ) résulte en
un binding (
) où le nom du service s est envoyé à la place l où il est requis.
Figure 15. Déclaration d’un service fourni en π-calculus
Figure 16. Déclaration d’un service requis en π-calculus
Figure 17. Déclaration d’un binding en π-calculus
Dans Darwin, chaque composant primitif est représenté par un agent qui est une composition des
agents Prov et Req qui gèrent ces services et des agents qui définissent son comportement. Une configuration
architecturale est représentée par une composition des agents représentants les instances de ses composants
et des agents représentant les bindings (simples ou hiérarchiques pour les cas des composants composites).
Les instanciations et les bindings se font de façon concurrente. De plus, pour supporter la reconfiguration
dynamique des architectures, Darwin offre deux types d’instanciations : l’instanciation retardée (lazy) et
l’instanciation dynamique. L’instanciation retardée consiste à instancier un composant seulement lorsque ses
services sont requis par d’autres composants. L’instanciation dynamique, quant à elle, est supportée par des
constructions qui permettent d’inctancier les composants pendant l’exécution.
LATECE Technical Report, October 2006
Page 32
Darwin est supporté par un environnement appelé Regis (réf) où les composants primitifs sont
implantés en C++. Regis offre un éditeur graphique permettant différentes vues sur le système en cours de
développement. Il permet aussi certains types d’analyses.
Finalement, malgré son utilisation du langage π-calculus, Darwin ne décrit pas les propriétés des
composants et des services d’une configuration. Aussi le support des styles architecturaux est limité à des
configurations paramétrées (Allen, 1997). De plus, les interactions ne sont pas explicitement spécifiées par
des connecteurs ce qui ne favorise pas leur réutilisation.
4.2.2
RAPIDE
Dans RAPIDE, développé par (Luckham et al., 1995) à l’Université de Stanford, une architecture est
composée d’un ensemble de spécifications de modules (interfaces), un ensemble de règles de communication
et d’interaction entre ces interfaces et un ensemble de contraintes formelles définissant des patrons de
communication. Ces constructions architecturales ont un modèle d’exécution basé événement. En fait,
RAPIDE permet la spécification des systèmes comme des ensembles d’événements partiellement ordonnés
(poset : Partially Ordered event Set). Un composant peut être formé de plusieurs processus. Ces processus
observent et réagissent au poset généré par l’exécution d’une architecture.
RAPIDE comprend cinq parties ou langages : le langage des types pour décrire les interfaces des
composants, le langage d’architecture pour décrire le flux des événements entre composants, le langage de
spécification pour écrire des contraintes sur le comportement des composants, le langage exécutable pour
écrire des modules exécutables et le langage de patron pour décrire des patrons d’événements.
Un composant comprend deux parties : une interface et un module. Une interface définit l’ensemble
des services fournis ou requis par le module, autrement dit, elle définit un type d’interaction. Le module
encapsule un prototype exécutable du composant ou il le définit hiérarchiquement comme une architecture
de d’autres composants.
Les éléments déclarés dans une interface sont : le type, les fonctions (communication synchrone), les
actions (communication asynchrone), les contraintes et le comportement. Les fonctions et les actions peuvent
avoir une visibilité de type public, private ou extern. Le type public fait référence à des services requis par
d’autres modules, le type extern à ceux fournis par le module et le type private à ceux fournis par le module
et qui sont visibles uniquement aux autres modules de même type.
LATECE Technical Report, October 2006
Page 33
Les contraintes, quant à elles, sont écrites avec le langage de spécification. Ce sont des patrons
d’événement qui contraignent le comportement visible d’un module. Les contraintes permettent de détecter
les violations de conformité à l’interface par les modules pendant l’exécution.
Dans RAPIDE, une interface peut hériter d’une autre en utilisant une déclaration de dérivation.
RAPIDE sépare l’héritage d’interface de l’héritage d’implémentation.
Une interface peut contenir la description du comportement du module (clause behavior). Cette
description est écrite dans le langage d’architecture. Elle est spécifiée sous forme de règles de transition
d’état où le composant observe un patron d’événements (trigger) puis génère un patron associé
d’événements (body) en réponse. RAPIDE définit plusieurs opérateurs exprimant la dépendance entre
événements (→ : dépendance causale, || : indépendance, and : simultanéité,…). Un patron d’événement est
construit grâce à ces opérateurs. Le comportement est utilisé comme une contrainte contre laquelle
l’exécution du module est vérifiée.
Une version simplifiée du standard X/Open DTP (distributed transaction processing) est utilisée
comme exemple (Fig.18). Elle comprend une application (AP), un gestionnaire de transaction (TM) et un ou
plusieurs gestionnaires de ressources (RMs).
Application Program (AP)
Transaction Manager (TM)
Resource Managers (RMs)
Figure 18. Architecture X/Open DTP
Les modules Application et Resource peuvent être décrits avec RAPIDE comme suit :
type Application is interface
extern action Request(p : params);
public action Results(p : params);
behavior
(?M in String) Receive(?M) => Results(?M);
LATECE Technical Report, October 2006
Page 34
end Application;
type Ressource is interface
extern action Results(Msg :string) ;
public action Receive(Msg :string) ;
end Ressource;
La première interface indique qu’un module Application peut appeler l’action Request et qu’il
fournit l’action Results. La partie behavior stipule que lorsqu’un événement Receive est reçu, un événement
Results est généré avec le même paramètre M.
Une architecture, dans RAPIDE, est un module avec un type d’interface. Elle comprend un ensemble
de composants et connexions. Elle définit le flux de données et la synchronisation entre modules en utilisant
leurs interfaces. La connexion définit un flux causal d’événements ou un appel de fonction entre composants.
Elle peut aussi relier les événements de l’interface de l’architecture et ceux des interfaces de ses composants.
L’interface Application peut être connectée d’une façon simple à l’interface Resource comme suit :
architecture AP_RM_Seulement return X/Open is
P :Application;
Q :Ressource;
…
connect (?M in string)
P.Request(?M) to Q.Receive(?M);
…
end AP_RM_Seulement;
Cette architecture spécifie que chaque fois que l’application P génère un événement Request, un
événement Receive est généré dans la ressource R avec la même donnée. La connexion « to » relie deux
événements simples, elle est dite basique. Il existe d’autres types d’opérateurs permettant des connexions
plus complexes, comme l’opérateur de diffusion « ||> » et l’opérateur pipe-line « => ».
Pour finir, en utilisant un modèle d’événement, RAPIDE permet la spécification de la dynamique
d’un système. En plus, il est doté d’un environnement textuel et graphique pour décrire une architecture. Cet
environnement inclut un analyseur syntaxique, un compilateur et un outil permettant l’analyse d’une
architecture par simulation. L’inconvénient majeur de RAPIDE est qu’il ne permet pas de spécifier les
LATECE Technical Report, October 2006
Page 35
connecteurs d’une façon explicite. Ce qui ne permet pas leur manipulation durant la conception ni leur
réutilisation. Pour ce qui est des propriétés non fonctionnelles, RAPIDE comme la plupart des ADLs, ne
supporte pas leur modélisation.
5.
Synthèse sur les ADLs
Comme le montre la table 1, même s’ils emploient parfois des terminologies différentes, tous les
ADLs considérés permettent de spécifier un composant, son interface et son type. Par contre, ils ne spécifient
pas tous de façon explicite un connecteur (ex : Darwin et Rapide). Les ADLs qui ne permettent pas de définir
un connecteur de façon explicite ne permettent pas non plus de spécifier son interface et ne favorisent pas sa
réutilisation. Ils ne différencient pas entre type et instance d’un connecteur et n’offrent pas de support à son
évolution (Medvidovic et al., 2002). La majorité des ADLs ne supportent pas non plus l’évolution d’un
composant ou d’une architecture mais les décrivent de façon statique (Table 3).
Certains ADLs (ex : Rapide, UniCon, Wright) permettent de spécifier la sémantique des composants
et des connecteurs lorsqu’ils les spécifient explicitement. La sémantique est exprimée de façon très variée
(Table 2). Dans UniCon, elle se limite à une liste de propriétés alors que dans Wright elle est exprimée
formellement avec le langage CSP. De façon générale, les langages « génériques » (Aesop, ACME) se
concentrent sur l’aspect structurel et négligent l’aspect sémantique. Par contre, les langages qui se
concentrent sur l’aspect dynamique des architectures (Darwin, Rapide), ne modélisent pas explicitement tous
les concepts architecturaux, en particulier les connecteurs (Table 1). À l’exception de UniCon, aucun ADL
ne supporte vraiment la spécification des propriétés non fonctionnelles des composants et des connecteurs
(Table 2).
LATECE Technical Report, October 2006
Page 36
ACME
Aesop
C2
Darwin
Rapide
UniCon
Wright
Composant
Composant
Composant
générique à
spécialiser
Composant
Interface et
module
Connecteur
explicite
Connecteur explicite Connecteur
générique à
explicite
spécialiser
Composant
(ensemble
prédéfini de
types)
Connecteur
explicite
(ensemble
prédéfini de
types)
Composant
Connecteur
Composant
(interface sous
forme de
services)
connecteur
non explicite,
Bindings des
services.
Composant
composite
«Attachments»
spécifie
explicitement une
configuration
comme un
assemblage
d’instances de
composants et de
connecteurs.
Non
Spécifie
explicitement un
style en utilisant
des types de
composants, de
connecteurs,
d’interfaces et des
prédicats.
Configuration «Attachments»
spécifie
explicitement une
configuration
comme un
assemblage
d’instances de
composants et de
connecteurs.
Topologie
explicite de
l’architecture
Composant
composite
Style
Non
Configuration
paramétrée
Configuration
générique à
spécialiser. Des
bindings permettent
de faire la liaison
entre la
configuration
interne et l’interface
externe d’un
composant ou d’un
connecteur.
Des «templates»
Style générique à
sont regroupés pour spécialiser.
définir un style
architectural.
connecteur
non explicite,
connexion par
flux causal
d’événements
ou par appel
de fonction
«connect» :
flux causal
d’événements
ou appel de
fonctions
entre
composants.
Non
Connecteur
explicite
Table 1. Support par les ADLs des exigences minimales et fondamentales
LATECE Technical Report, October 2006
Page 37
ACME
Aesop
C2
Darwin
Rapide
UniCon
Wright
Non. Il peut se
baser sur la
sémantique de
d’autres langages
grâce à son système
d’annotations avec
des listes de
propriétés. Ces
annotations ne sont
pas interprétables.
À travers les
interfaces
uniquement.
Spécifiée au besoin
par des langages
spécifiques aux
styles.
«behavior»
décrit le
comportement
d’un
composant.
Pré et postconditions des
méthodes.
Modèle
d’interaction
et de
composition
en π-claculus
Comportemen
t dynamique
décrit par des
poset
(ensembles
d’événements
partiellement
ordonnés)
Liste de
propriétés
associée à un
composant ou
connecteur.
Comportements
dynamique des
composants et des
connecteurs
décrits en CSP.
Les contraintes
supportées par les
méthodes des types.
Contraintes de Non
style et à
travers les
interfaces.
Spécifiées par
le langage de
spécification.
Liste de
propriétés
associée à un
composant ou
connecteur.
Composition
hiérarchique
un composant ou
un connecteur peut
avoir plusieurs
représentations de
niveau plus bas.
Composants et
Connecteurs
peuvent avoir
plusieurs
représentations de
niveau plus bas.
Composant
spécifié sous
forme
d’architecture.
Composant
composite
dont les
services sont
liés aux
services des
composants
qu’il contient.
Les composants
peuvent être
composites.
Propriétés
non
fonctionnelle
s
Non. il permet de
spécifier des
annotations
exprimées dans
différents ADLs
mais elles ne sont
pas interprétables
Non. Permet
d’exprimer des
propriétés de façon
textuelle et non
interprétable.
Non
Non
Correspondan
ce entre
événements de
l’interface
d’une
architecture et
ceux de
l’interface
d’un
composant.
Non
Spécifiées par des
types d’interfaces
dans le cas des
composants et
connecteurs.
Utilise des
prédicats pour
exprimer les
contraintes dans
la spécification
d’un style.
Composants et
Connecteurs
peuvent être
composites.
Sémantique
Contraintes
Certaines
propriétés
comme la
planification
(schedulability)
Non
Table 2. Support par les ADLs des exigences souhaitables
LATECE Technical Report, October 2006
Page 38
ACME
Aesop
C2
Darwin
Rapide
UniCon
Wright
Réutilisation
Utilise un
«template» pour
définir une
structure
syntaxique
paramétrée que l’on
peut instancier
plusieurs fois.
Les composants, les
connecteurs et les
styles peuvent être
étendus.
Les
composants et
les
connecteurs
peuvent être
étendus.
Les types
peuvent être
paramétrés.
Héritage
d’interface et
héritage de
modules. Les
types peuvent
être
paramétrés.
Les types des
composants et
des connecteurs
peuvent être
réutilisés.
Évolution
Non. Évolution des
composants et des
connecteurs via le
sous-typage
Non. Évolution par
sous-typage.
Non.
Évolution des
composants et
connecteurs
via le soustypage.
Instanciation
dynamique
des
composants.
Non
Support
d’outil
Outil de
visualisation.
Éditeur graphique et
générateur de code
pour le style pipefilter. Permet
d’intégrer des outils
externes.
Éditeur
textuel et
graphique,
analyseur de
la syntaxe et
la sémantique
et générateur
de code.
Éditeur
textuel et
graphique,
analyseur
syntaxique et
générateur de
code C++.
Évolution des
composants
via le soustypage.
Évolution de
la
configuration
Outils de
simulation et
d’analyse.
Les types des
composants et des
connecteurs
peuvent être
réutilisés. Les
types peuvent être
paramétrés. Les
styles peuvent
être étendus.
Non. Évolution
par le
paramétrage des
types.
Outils :
modélisation,
analyse
syntaxique et
génération de
code en C.
Édition textuelle,
analyseur de
syntaxe et type,
analyseur pour
détection des
inter-blocages.
Table 3. Support par les ADLs des exigences désirables mais non fondamentales
6.
La description architecturale dans UML
Une description architecturale doit être comprise et manipulée par plusieurs intervenants qui ont peu
de connaissance dans le domaine des spécifications formelles. C’est l’une des raisons pour lesquelles
plusieurs tentatives ont été faites pour utiliser ou étudier la possibilité d’utilisation d’UML (Unified
Modeling Language) (UML2.0, 2005) (UML2.0, 2006) comme un langage de description des architectures.
L’autre raison est que UML est un standard incontournable qui est accompagné par plusieurs outils de
support. En effet, utiliser UML pour décrire les architectures, permettra à ses utilisateurs de bénéficier des
analyses puissantes offertes par les ADLs et aux utilisateurs des ADLs d’utiliser les outils UML.
6.1
Présentation sommaire d’UML
UML est un langage de modélisation résultant de l’unification d’un certain nombre de méthodes
(OMT, OOSE, OOAD, etc.). Il décrit un système en utilisant une notation graphique orientée objet. Il a une
syntaxe semi-formelle et une sémantique. Pour modéliser un système, UML fournit plusieurs modèles
chacun décrivant un aspect. Ces modèles sont exprimés sous forme de diagrammes (de classes, d’états, de
packages, de cas d’utilisation, de déploiement).
LATECE Technical Report, October 2006
Page 39
La sémantique d'UML manque de précision, ce qui limite l'utilisation des modèles UML à un moyen
de compréhension et de communication ou au plus à la génération de la structure d'un système. Cependant,
UML offre des moyens qui permettent d'étendre et de préciser la sémantique des éléments de ses modèles.
Les mécanismes d'extension sont les valeurs marquées (tag) (attributs associés à des éléments du modèle),
les contraintes (restrictions sémantiques sur les éléments du modèle), les stéréotypes (regroupent des
contraintes et des valeurs marquées sous un nom pour pouvoir les appliquer à des éléments du modèle) et les
profils (regroupent des stéréotypes, des valeurs marquées et des contraintes spécifiques à la modélisation
dans un domaine particulier). Les contraintes sont exprimées d’une façon non ambiguë avec le langage
formel OCL (Object Constraint Language) (OCL2.0, 2005). Ce dernier permet l’application de ces
contraintes sur un élément ou une collection d’éléments.
UML est défini selon l’architecture à 4 couches de méta-modélisation de l’OMG (OMG, 2003)
(méta-méta-modèle, méta-modèle, modèle, les objets de l’utilisateur). Chaque couche de cette architecture
définit des modèles pour spécifier les modèles de la couche inférieure. Ainsi, le méta-modèle est lui même
un modèle UML qui spécifie la syntaxe abstraite des modèles UML. Ces derniers décrivent l’information
particulière à un domaine, et sont instanciés par les objets de l’utilisateur.
6.2
Les approches basées sur UML1.x
Plusieurs chercheurs (Garlan et al., 2002) (Medvidovic et al., 2002) (Baresi et al., 2003) (Zarras et
al., 2001) (Perez-Martinez, 2003) se sont intéressés à la possibilité de modéliser une architecture en utilisant
UML. Plusieurs stratégies ont été adoptées. Medvidovic et al. (Medvidovic et al., 2002) ont étudié deux
stratégies conformes au standard UML. La première stratégie suggère d’utiliser UML tel qu’il est, pour
représenter les concepts architecturaux. La seconde stratégie consiste à contraindre UML en utilisant ses
extensions.
Dans la première stratégie, en utilisant UML pour modéliser des applications de la même façon
qu’un ADL, Medvidovic et al. ont représenté certaines entités architecturales ayant différentes
responsabilités (composant et connecteur) avec le même concept (Classe). Les règles d’un style architectural
sont représentées par des contraintes structurelles, mais elles ne sont pas directement reflétées dans le modèle
UML comme cela est possible avec un ADL. En plus, le modèle UML doit être documenté pour empêcher
des modifications futures non conformes aux règles du style. En ce qui concerne l’aspect dynamique de
l’architecture, il peut être modélisé avec les diagrammes d’UML comme les diagrammes de séquence, de
collaboration et d’état. Toutefois, il n’est pas garanti que les comportements et interactions prévus sont
correctement et fidèlement modélisés.
LATECE Technical Report, October 2006
Page 40
La seconde stratégie utilise le langage OCL pour ajouter des contraintes au niveau du méta-modèle
d’UML. Elle consiste à définir des stéréotypes et les appliquer aux instances d’une ou plusieurs méta-classes
d’UML pour contraindre leurs sémantiques à celle de l’ADL associé. Medvidovic et al. ont illustré
l’approche par des extensions correspondant à 3 ADLs : C2, WRIGHT et RAPIDE. La prise en charge des
règles du style C2 a été relativement simple dans la mesure où le style a été entièrement exprimé par des
classes stéréotypées et leurs associations. Dans le cas du langage WRIGHT, il fallait modéliser la sémantique
des entités architecturales : des machines à état UML ont été utilisées pour modéliser le comportement et les
interactions d’un composant ou connecteur. De même, les comportements des composants dans RAPIDE ont
été modélisés avec des machines à état UML. Une correspondance a été établie entre les événements dans
RAPIDE et les signaux dans les diagrammes d’état d’UML. Toutefois, le modèle devient très compliqué vu
qu’il faut maintenir l’information à propos de l’ordre causal des événements dans RAPIDE.
Cette deuxième stratégie souligne les limitations sémantiques d’UML quant à la modélisation de
certaines préoccupations architecturales. En plus, elle utilise OCL qui peut ne pas être supporté par les outils
UML vu qu’il est considéré comme une partie non interprétée d’UML. Une autre limite de la stratégie est
qu’elle n’offre aucune garantie que les règles d’un style architectural donné seront toujours respectées. Et
finalement, les deux stratégies nécessitent des mises en correspondances pour chaque ADL.
Garlan et al. (Garlan et al., 2002) considèrent quatre stratégies pour la représentation en UML des
architectures. Les stratégies diffèrent par le choix des constructions UML utilisées pour spécifier le type d’un
composant et ses instances. La 1ère stratégie représente le type d’un composant par une classe et les instances
du composant par des objets. La 2ième stratégie propose de représenter aussi bien les composants que leurs
instances par des classes. La 3ième stratégie consiste à représenter un composant architectural par un
composant d’UML. Un composant dans UML1.x décrit un artefact d’implantation et non un composant au
sens des ADLs. La 4ième stratégie modélise un composant comme un sous-système UML. Le choix des
constructions représentant les ports, les connecteurs, les configurations (systèmes) et les représentations
(sous-systèmes) dépend des constructions utilisées pour modéliser un composant et ses instances. Un
connecteur, par exemple, peut être modélisé par une association, une classe d’association, une classe, une
dépendance entre composants, un composant ou un sous-système.
Les quatre stratégies ont été examinées en fonction de la complétude, la lisibilité et la conformité
sémantique de la description architecturale qu’elles permettent. La conformité sémantique signifie ici que le
modèle décrivant une architecture est un modèle UML légal et que son interprétation est identique à celle de
la description fournie par un ADL. Selon Garlan et al., la majorité des stratégies ne sont pas complètes ou
LATECE Technical Report, October 2006
Page 41
conformes sémantiquement. De plus, les stratégies assurant un degré élevé de complétude sont aussi celles
qui ne facilitent pas la lisibilité et inversement.
Zarras et al., (Zarras et al., 2001) proposent, quant à eux, un profile UML pour décrire les
architectures. Ils ont donc défini un stéréotype pour chaque concept architectural (i.e. composant, connecteur
et configuration). L’utilisation des mécanismes standards d’extension offerts par UML (tags, contraintes,
stéréotypes et profils), pour supporter les descriptions architecturales a l’avantage considérable de permettre
l’utilisation des différents outils existants supportant UML. Cela n’est pas le cas quand on étend le métamodèle UML en introduisant de nouveaux concepts (e.g. voir (Perez-Martinez, 2003)).
D’autres chercheurs ont adopté une démarche complètement différente des stratégies que nous avons
citées. Baresi et al. (Baresi et al., 2003) utilisent des diagrammes de classes pour modéliser la partie statique
d’un style architectural. Les composants et leurs relations, dans une architecture concrète, sont représentés
par des classes et leurs associations. Des contraintes et des règles peuvent être ajoutées au modèle sous forme
d’expressions OCL. La particularité de l’approche est qu’elle utilise des règles de transformation de graphes
pour modéliser les aspects dynamiques d’un style architectural. Une règle est représentée par une paire
d’instances de graphe : une instance pour définir les pré-conditions pour l’application de la règle et une
instance pour décrire les post-conditions. Ces deux instances sont intégrées dans un seul diagramme de
collaboration UML où les éléments qui sont à supprimer (après application de la règle) sont marqués du tag
{destroyed} et ceux à ajouter ont un tag {new}. Des techniques de validation et de vérification sont
proposées pour démontrer la correction et la cohérence des descriptions architecturales basées sur les
transformations de graphes.
Les règles de transformation de graphes présentent une méthode intéressante pour spécifier l’aspect
dynamique d’une architecture. Cependant, il n’est pas facile d’exprimer les règles, les contraintes et les
mécanismes de contrôle d’une façon claire et précise tout en garantissant des analyses très puissantes. Aussi,
Il n’y a pas d’outils supportant l’approche.
Ce que l’on peut retenir de toutes ces études est que UML1.x ne favorise pas une démarche unique et
meilleure pour décrire les concepts architecturaux (Garlan et al., 2002). En effet, la majorité des travaux
étudiés ont souligné l’inadaptabilité d’UML1.x à la spécification explicite et complète des architectures.
LATECE Technical Report, October 2006
Page 42
6.3
UML2.0
6.3.1
Le modèle de composant
UML 2.0 a introduit de nouvelles constructions qui le rendent plus adapté au développement à base
de composants et à la spécification des descriptions architecturales. Dans UML2.0, un composant possède un
certain nombre d’interfaces fournies et d’interfaces requises. Une interface fournie spécifie les
fonctionnalités fournies par un composant et une interface requise spécifie les fonctionnalités nécessaires au
fonctionnement du composant. Le type d’un composant est donc défini par ses interfaces. La figure 19
montre un exemple de composant qui a deux interfaces fournies et trois interfaces requises (Person, Invoice
et OrderableItem). Un composant interagit avec son environnement à travers des points d’interaction appelés
ports. Les ports sont typés : un port fourni (resp. requis) a pour type une interface fournie (resp. requise). Les
interfaces d’un composant sont exposées via les ports.
Figure 19. Exemple de composant
UML2.0 distingue les composants de base (atomiques) des composants composites appelés
structures composites. Le paquetage BasicComponents (Fig.20) du méta-modèle d’UML2.0 définit un
composant atomique comme un élément exécutable dans un système. Un composant atomique est un sous
type de la méta-classe Class. Il peut donc avoir des attributs et des opérations comme il peut participer à des
relations de généralisation ou d’association. Un composant de base possède une spécification externe sous
forme d’interfaces fournies et requises et une implantation interne composée d’un ou plusieurs Classifiers
qui réalisent son comportement. En effet, un composant est défini comme une unité qui encapsule l’état et le
comportement d’un ensemble de classifiers. Le paquetage PackagingComponents (Figure 21), quant à lui,
étend le concept de composant de base pour spécifier une structure composite qui est définie comme un
block de construction pouvant contenir et importer un ensemble d’éléments.
LATECE Technical Report, October 2006
Page 43
Figure 20. Les méta-classes définissant les composants de base
Figure 21. Les méta-classes définissant les composants composites
Un composant peut être représenté de différentes façons. On peut le représenter par une classe avec
des compartiments contenant les interfaces, les attributs et les opérations. La représentation peut être une vue
externe (« boite blanche ») où on montre seulement les interfaces du composant dans un compartiment de la
classe. On peut attacher (optionnel) à une interface, un port ou le composant lui-même la description de son
comportement sous forme d’une « machine à états ». On peut aussi représenter une interface comme un
classifier ce qui permet d’afficher sa signature complète. Dans la vue interne («boite blanche»), par contre,
des compartiments additionnels permettent de montrer les Classifiers réalisant le composant et aussi des
listes des parties ou connecteurs faisant partie du composant ou d’artefacts d’implantation. Pour une
présentation plus détaillée d’un composant (ex : Fig.22), on peut définir sa structure interne en terme de ses
parties (instances de classes) et les connecteurs (instances d’associations) entre ces parties.
La liaison entre les ports ou les interfaces des composants se font par des connecteurs. On distingue
entre connecteurs de délégation et connecteurs d’assemblage. Les connecteurs de délégation relient les ports
d’un composant aux éléments qu’il contient et qui réalisent son comportement. Ils modélisent la
décomposition hiérarchique d’un comportement. La délégation peut se faire sur plusieurs niveaux
LATECE Technical Report, October 2006
Page 44
(composition imbriquée). Deux interfaces (ports) reliées par un connecteur de délégation doivent être de type
compatibles (les deux sont requises ou les deux sont fournies). Dans la figure 22, par exemple, on peut voir
deux connecteurs de délégation (marqués par le mot clé « delegate »). Un connecteur d’assemblage relie
deux composants, il joint une interface requise (port requis) à une interface fournie (un port fourni). Un
exemple de connecteur d’assemblage est monté à la figure 23. Ce connecteur relie l’interface requise
OrderableItem d’une instance du composant Order à l’interface fournie OrderableItem d’une instance du
composant Product. Le type d’un connecteur est spécifié par un attribut (ConnectorKind) dont le type est
une énumération ({assembly, delegation}).
Figure 22. Une vue «boite blanche» de la structure interne d’un composant composite
Figure 23. Un connecteur d’assemblage reliant les instances des composants Order et Product
Plusieurs paquetages du méta-modèle UML2.0 permettent de spécifier les structures composites. Le
paquetage InternalStructure (Figure 24 et 25) permet de spécifier les structures internes des composants. La
méta-classe StructuredClassifier spécifie un classifier dont le comportement peut être décrit complètement
ou partiellement par la collaboration d’instances qu’il contient ou référence. La méta-classe Property
LATECE Technical Report, October 2006
Page 45
modélise les propriétés d’une instance de StructuredClassifier, en particulier, elle spécifie les instances
pouvant être contenues dans l’instance d’un classifier (association part dans la figure 24). Le concept
ConnectableElement représente des rôles pouvant être attribués aux instances de Property contenues dans
l’instance d’un classifier. Ces rôles peuvent être reliés par des connecteurs. Un connecteur (Figure 25) est un
lien qui permet aux instances de communiquer entre elles. Il peut représenter une instance d’une association
ou un moyen de communication tel qu’un passage de paramètre, partage de variable, etc. Chaque extrémité
de connecteur ConnectorEnd représente un rôle distinct faisant partie de la communication représentée par le
connecteur. Un exemple de classe composite contenant 4 parties est montrée à la figure 26.
Figure 24. Extrait du paquetage InternalStructure
Figure 25. Extrait du paquetage InternalStructure
LATECE Technical Report, October 2006
Page 46
Le paquetage Ports (Figure 27) fournit les concepts nécessaires pour spécifier les points
d’interaction entre un classifier et son environnement. Le concept central dans ce paquetage est la métaclasse Port qui est défini comme une propriété d’un classifier (EncapsulatedClassifier dans la figure 27) qui
est une extension de la métaclasse StructuredClassifier. EncapsulatedClassifier est un classifier ayant des
ports typés par des interfaces. La métaclasse Port représente un point d’interaction entre un classifier et son
environnement ou entre un classifier et ses parties internes. L’attribut isBehavior de Port spécifie, quand il
est mis à « true », que les requêtes reçues via ce port seront traitées par l’instance du classifier qui contient le
port et non pas par les instances pouvant être contenues par ce classifier. Par défaut, isBehavior est mise à
« false ». L’attribut isService, quant à lui, spécifie, quand il est mis à « true », que le port est utilisé pour
fournir une fonctionnalité publiée d’un classifier, sinon le port ne représente pas une fonctionnalité visible
essentielle du classifier. Par défaut, un port est visible. La figure 22 montre une structure composite (store)
ayant deux ports. Par contre, la figure 26 montre que les connecteurs ne sont pas attachés nécessairement aux
parties d’une structure composite via des ports.
Figure 26. Exemple de diagramme de structure
Figure 27. Le paquetage Ports
LATECE Technical Report, October 2006
Page 47
Le paquetage Collaborations (Figure 28 et 29) fournit les mécanismes permettant de décrire la
collaboration entre un ensemble d’instances en leur attribuant des rôles qui sont typés par les interfaces des
instances auxquelles ils sont associés. Le classifier est donc étendu de façon à ce qu’il puisse utiliser des
collaborations appelées CollaborationUse (Figure 29). Une collaboration spécifie un ensemble de
participants nécessaires pour réaliser une tâche spécifique. Ces participants sont spécifiés par des rôles reliés
par des connecteurs. Les rôles sont typés par des interfaces. Une collaboration n’est pas instanciable
directement. Une CollaborationUse représente l’application du patron décrit par une collaboration dans un
contexte spécifique. En effet, les propriétés d’un classifier sont associées aux rôles d’une collaboration par
l’intermédiaire des bindings des rôles d’une CollaborationUse. Une des CollaborationUse (représentée par
l’association representation de la figure 29) d’un classifier peut décrire le comportement du classifier luimême. Les collaborations sont très utiles pour décrire les patrons de conception.
Figure 28. Extrait du paquetage Collaborations
Figure 29. Utilisation des collaboration et association des rôles
LATECE Technical Report, October 2006
Page 48
Finalement, le paquetage StructuredClasses (partie gauche de la figure 30) étend la méta-classe
EncapsulatedClass pour définir des classes pouvant avoir des ports et une structure interne et, le paquetage
Actions (partie droite de la figure 30) étend les actions de base visant un objet pour introduire des actions
spécifiques (InvocationAction) aux structures composites (ex : envoi de messages à travers un port).
Figure 30. Les paquetages StructuredClasses et Actions
6.3.2
Le modèle de déploiement
L’aspect implémentation d’une architecture est décrit par le paquetage de déploiement qui est
composé de trois paquetages spécifiant un certain nombre de constructions qui permettent de définir une
architecture d’exécution. Le paquetage Artifacts (Figure 31) définit la construction Artifact qui étend un
Classifier pour représenter un élément concret (physique) résultant du processus de développement (e.g.
fichier source, fichier de modèle, table dans une base de données, etc.). Un artifact peut être construit à partir
de d’autres artifacts et il manifeste un ensemble d’éléments qui ont servi à sa génération. Une instance
particulière d’un artifact est déployée en une instance d’un nœud.
Figure 31. Le paquetage Artifacts
LATECE Technical Report, October 2006
Page 49
Le paquetage Nodes (Figure 32 et 33) définit le concept de nœud et la relation basique de
déploiement entre les artifacts et les nœuds. Un nœud représente soit un composant hardware ou un
environnement d’exécution, c’est une ressource sur laquelle des artifacts peuvent être déployés. Les noeuds
sont définis de façon imbriquée. Ils sont connectés par des chemins (paths) de communication pour créer un
système relié. Un chemin de communication est en fait une association entre les localisations de deux
artifacts déployés. Ces localisations sont appelées DeploymentTargets. Le déploiement est l’allocation d’un
artifact ou d’une instance d’artifact à une cible de déploiement. Un artifact déployé est donc un artifact ou
une instance d’artifact. Un nœud est un sous-type de Class et peut donc avoir une structure interne.
Le paquetage ComponentDeployments (Figure 34) étend le modèle de dépoilement de base pour
supporter des mécanismes de déploiement de certaines technologies communes de composants. Il définit le
concept « spécification de déploiement » qui décrit les paramètres d’exécution d’un artifact composant
déployé sur un nœud. L’ensemble des propriétés de déploiement d’une spécification sont spécifiques à un
certain type de conteneur (Container).
Figure 32. Le concept Noeud
LATECE Technical Report, October 2006
Page 50
Figure 33. Définition de la relation de déploiement
Figure 34. Le paquetage ComponentDeployments
Un exemple de diagramme de déploiment est montré à la figure 35. Sur ce diagramme, il y a deux
types de nœud (AppServer et DBServer) communiquants entre eux. Des artifacts (Order.jar,
RequestHandler.jar) dont déployés sur un des nœuds.
Figure 35. Exemple de diagramme de déploiement
LATECE Technical Report, October 2006
Page 51
6.3.3
Le modèle comportemental
Le comportement d’une classe peut être décrit par des interactions, des activités ou des machines à
états. « Une action représente l’unité fondamentale de la spécification du comportement ». Les actions
peuvent être reliées à des activités, des machines à états ou d’autres comportements. Une action peut être une
action d’invocation (e.g. appel d’opération, envoi de message, etc.), une action de réorganisation structurelle
(e.g. création d’objet, suppression, etc.) ou une action de calcul (fonction qui prend un ensemble d’entrées et
donne un ensemble de sorties). Cette distinction permet une correspondance propre avec le modèle physique.
Les actions reçoivent et fournissent des valeurs par l’intermédiaire d’éléments typés appelés « pins ». Les
activités spécifient des séquences d’actions et des conditions pour coordonner ces séquences. La figure 36
montre un exemple d’activité décrivant un processus de commande avec des pré- et post-conditions et
recevant un paramètre en entrée. Un des changements majeurs apportés par UML2.0 est l’intégration des
activité avec les actions qui leur sont reliées.
Figure 36. Exemple d’une activité
« Une interaction est une unité de comportement qui se concentre sur un échange observable
d’informations entre des éléments connectables ». Elle peut être présentée par différents types de
diagrammes : diagrammes de séquence, diagrammes de communication (appelés diagrammes de
collaboration dans UML1.x) et diagrammes d’interaction. Un exemple d’interaction décrite par un
diagramme de séquence est montré à la figure 37. De plus, une interaction peut être utilisée dans la
description d’une autre interaction (figure 38). Les diagrammes d’interaction, quant à eux, définissent les
interactions en utilisant des diagrammes d’activités et des diagrammes de séquence (figure 39).
LATECE Technical Report, October 2006
Page 52
Figure 37. Une interaction décrite par un diagramme de séquence
Figure 38. Une interaction qui référence d’autres interactions
LATECE Technical Report, October 2006
Page 53
Figure 39. Exemple de diagramme d’interaction
6.4
UML2.0 comme ADL
Par rapport aux versions précédentes d’UML, beaucoup de concepts ont été introduit par UML2.0
visant à améliorer le support offert pour les descriptions architecturales. Cependant, il y a encore différentes
façons de représenter certains concepts architecturaux avec UML2.0 (Ivers et al., 2004), ce qui ne facilite pas
la tâche des architectes. De plus, le concept de Connecteur n’est pas modélisé comme une entité de première
classe : la façon dont un connecteur est spécifié ne permet pas de lui attribuer une interface ni une
LATECE Technical Report, October 2006
Page 54
sémantique comme le font certains ADLs (e.g. Wright). Aussi, UML2.0 ne décrit pas les propriétés
fonctionnelles et n’offre pas un support explicite pour la modélisation des styles architecturaux. Toutefois,
on peut représenter un style architectural en utilisant les mécanismes standards d’extensions offerts par
UML, en particulier les profiles.
7.
Conclusion
Les ADLs se sont intéressés à la spécification des architectures d’une façon formelle et rigoureuse
mais souvent très spécialisée. Ils permettent des analyses spécifiques puissantes. Cependant, ils sont
généralement difficiles pour un concepteur non expérimenté. Ce qui limite leur intégration dans le processus
de développement et leur utilisation dans le milieu industriel. En plus, la majorité des ADLs ne permettent
pas de raffiner le modèle architectural de façon à aller jusqu’à la génération de code.
Pour sa part, UML vise la modélisation en large sous une perspective orientée objet. Il est supporté
par plusieurs outils dont certains vont jusqu’à la génération de l’implémentation d’un système. UML favorise
une notation flexible et facile à utiliser par les concepteurs ce qui en fait un langage moins formel et moins
rigoureux que les ADLs.
8.
Références
Allen R.J, « A Formal Approach to Software Architecture », PhD Thesis, CMU-CS-97-144, 1997.
Allen R.J, Garlan D., « A Formal Basis for Architectural Connection », ACM Transactions on
Software Engineering and Methodology, Vol. 6, No. 3, July 1997, p.213–249.
Baresi L., Heckel R., Thöne S., Varró D., « Modeling and Analysis of Architectural Styles Based on
Graph Transformation », The 6th ICSE Workshop on Component Based Software Engineering: Automated
Reasoning and Prediction, May 3-4, 2003.
P.C. Clements, “A Survey of Architecture Description Languages”, Proceedings of the eighth Int'l
Workshop Software Specification and Design, Mars 1996.
Garlan D., Allen R., Ockerbloom J., « Exploiting Style in Architectural Design Environments »,
Proceedings of SIGSOFT '94 Symposium on the Foundations of Software Engineering, December 1994.
Garlan D., Shaw M., « An Introduction to Software Architecture », Carnegie Mellon University
Technical Report CMU-CS-94-166, January 1994.
LATECE Technical Report, October 2006
Page 55
Garlan D., « An introduction to the Aesop System », http://www.cs.cmu.edu/afs/cs/project/able
/www/aesop/html/aesop-overview.ps , 1995.
Garlan D., Monroe R.T., Wile D., « Acme: An Architecture Description Interchange Language »,
Proceedings of CASCON 97, Toronto, Ontario, November 1997, p.169-183.
Garlan D., Monroe R.T., Wile D., « Acme: Architectural Description of Component-Based
Systems », Foundations of Component-Based Systems, Leavens G.T. and Sitaraman M. (eds), Cambridge
University Press, 2000, pp. 47-68.
Garlan D., Cheng S.W., Kompanek A., « Reconciling the Needs of Architectural Description with
Object-Modeling Notations », Science of Computer Programming Journal, 44 (1), July 2002, p.23-49.
Hoare C. A. R., Communicating Sequential Processes, Prentice-Hall, Englewood Cliffs, N.J., 1985.
Ivers J., Clements P., Garlan D., Nord R., Schmerl B., Silva J.R.O, «Documenting Component and
Connector Views with UML 2.0 », Technical Report, CMU/SEI-2004-TR-008, avril 2004.
Le Métayer D., « Describing Software Architecture Styles Using Graph Grammars », IEEE
Transactions on Software Engineering, Vol.24, No.7, July 1998.
Luckham D.C., Kenney J.J., Augustin L.M., Vera J., Bryan D., Mann W., « Specification and
Analysis of System Architecture Using Rapide », IEEE Transactions on Software Engineering, Vol.21,
No.4, April 1995, p.336-355.
Magee J., Dulay N., Eisenbach S., Kramer J., « Specifying Distributed Software Architectures », the
5th European Software Engineering Conference (ESEC’95), Spain, 26 September 1995.
OMG Model Driven Architecture, http://www.omg.org/cgi-bin/doc?omg/03-06-01, June 2003.
Medvidovic N., Rosenblum D.S., Redmiles D.F., Robbins J.E., « Modeling Software Architectures
in the Unified Modeling Language », ACM Transactions on Software Engineering and Methodology, Vol.
11, N0 .1, January 2002.
Medvidovic N., Taylor R.N., « A classification and comparison framework for software architecture
description languages », IEEE Transactions on Software Engineering, Vol.26, No.1, p.70-93, January 2000.
LATECE Technical Report, October 2006
Page 56
Perez-Martinez J.E., « Heavyweight extensions to the UML metamodel to describe the C3
architectural style », ACM SIGSOFT Software Engineering notes, vol.28, No.3, Mai 2003.
Shaw M., Garlan D., “Characteristics of Higher-Level Languages for Software Architecture”,
Technical Report, CMUCS-94-210, Carnegie Mellon Univ., Dec. 1994.
Shaw M., DeLine R., Klein D.V., Ross T.L., Young D.M., and Zelesnik G., « Abstractions for
Software Architecture and Tools to Support Them », IEEE Trans. Software Eng., vol.21, no.4, p.314-335,
April 1995.
Taylor R.N., Medvidovic N., Anderson K.M., Whitehead Jr.E.J., Robbins J.E., Nies K.A., Oreizy P.,
Dubrow D.L., « A component- and message-based architectural style for GUI software », IEEE Transactions
on Software Engineering, Vol.22, NO.6, JUNE 1996.
UML2.0 Superstructure Specification: Adopted Specification, http://www.omg.org/docs/formal/0507-04.pdf , August 2005.
UML2.0 Infrastructure Specification: Adopted Specification. http://www.omg.org/docs/formal/0507-05.pdf, March 2006.
OCL2.0 Specification: Adopted Specification. http://www.omg.org/docs/ptc/05-06-06.pdf, June
2005.
Vestal S., « A Cursory Overview and Comparison of Four Architecture Description Languages »,
Honeywell technical Report, February 1993.
Zarras A., Issarny V., Kloukinas C., Nguyen V. K., « Towards a Base UML Profile for Architecture
Description », 1st ICSE Workshop on Describing Software Architecture with UML, Canada, pp. 22-26, 2001.
Zelesnik G., The UniCon Language User Manual, School of Computer Science Carnegie Mellon
Universtity,
Pittsburgh,
Juin
1996.
http://www.cs.cmu.edu/afs/cs/project/vit/www/unicon/reference-
manual/Reference_Manual_1.html
LATECE Technical Report, October 2006
Page 57

Documents pareils