Developpez.com - UML
X

Choisissez d'abord la catégorieensuite la rubrique :


Nouveautés UML 2.0 : Diagramme de séquence

3/12/2003

Par Cian (autres articles)
 

Cet article présente les nouveautés UML2.0 (noté également U2, UML2) en ce qui concerne le diagramme de séquence (appelé sequence diagram ou interaction diagram en anglais).

Les diagrammes de séquence sont couramment utilisés par nombre d'acteurs d'un projet, même quelque fois à leur insu, sans savoir qu'ils utilisent là un des diagrammes UML. En effet, le diagramme de séquence est une représentation intuitive lorsque l'on souhaite concrétiser des intéractions entre deux entités (deux sous-systèmes ou deux classes d'un futur logiciel). Ils permettent à l'architecte/designer de créer au fur et à mesure sa solution. Cette représentation intuitive est également un excellent vecteur de communication dans une équipe d'ingénierie pour discuter cette solution.
Les diagrammes de séquence peuvent également servir à la problématique de test. Les traces d'exécution d'un test peuvent en effet être représentées sous cette forme et servir de comparaison avec les diagrammes de séquence réalisés lors des phases d'ingénierie.

Les diagrammes de séquence tels que définis en UML1.x souffraient cependant d'un gros inconvénient. La quantité de diagrammes à réaliser pouvait atteindre un nombre conséquent dès lors que l'on souhaitait décrire avec un peu de détail les différentes branches comportementales d'une fonctionnalité. Le plus coûteux étant de remettre à jour ces diagrammes lors d'un changement au niveau des exigences ou bien du design.
Nous allons voir que UML2.0 souhaite donner plus de puissance de représentation à ces diagrammes grâce à de nouvelles constructions qui peuvent servir à réduire la quantité de diagramme à réaliser.

Notez que les traductions françaises des termes techniques sont personnelles.
Les notions abordées dans cet article sur les nouveautés UML2.0 sont : les "fragments combinés" (combined fragment ou inline frames), les opérateurs de fragments combinés, les "références" (interaction occurrence), les "continuations" (continuation symbol), la décomposition hiérarchique (part decomposition), les invariants ...


Avant-Propos
1. Les fragments combinés (appelé aussi combined fragment ou inline frame)
1.1. Opérateur "Alternative"
1.2. Opérateur "Option"
1.3. Opérateur "Break"
1.4. Opérateur "Parallel"
1.5. Opérateurs "Weak Sequencing" et "Strict Sequencing"
1.6. Opérateur "Negative"
1.7. Opérateur "Critical"
1.8. Opérateurs "Ignore" et "Consider"
1.9. Opérateur "Assertion"
1.10. Opérateur "Loop"
1.10. Combiner les opérateurs
2. Les références (appelé en anglais "interaction occurrence")
3. Les continuations (appelé en anglais "continuation symbol")
4. Messages Perdus / Trouvés
5. Décomposition hiérarchique de diagrammes de séquence (part decomposition)
6. Création d'objet et suppression
7. Contraintes de temps
8. Contraintes et invariants


Avant-Propos


Avant de présenter les nouveaux concepts du diagramme de séquence, je vous propose quelques rappels.
>> Diagramme de séquence :
Un diagramme de classe permet de décrire les intéractions entre différentes entités et/ou acteurs : par exemple des objets dans un modèle d'un logiciel, des sous-systèmes dans un modèle d'un système complet.
- Le temps est représenté comme s'écoulant du haut vers le bas le long des "lignes de vie" (lifeline) des entités.
- Des flèches représentent les messages qui transitent d'une entité vers l'autre. Le nom des message apparaît sur chaque flèche. Si l'extrémité de la flèche est pleine, le message est synchrone. Si l'extrémité de la flèche est creuse, le message est asynchone.

>> Message asynchrone :


>> Message synchrone :



1. Les fragments combinés (appelé aussi combined fragment ou inline frame)


Un fragment combiné représente des articulations d'intéractions. Il est défini par un opérateur et des opérandes. L'opérateur conditionne la signification du fragment combiné. Il existe 10 opérateurs définis dans la notation UML2.0. Les fragments combinés permettent de décrire des diagrammes de séquence de manière compacte. Les fragments combinés peuvent faire intervenir l'ensemble des entités participant au scénario ou juste un sous-ensemble.


1.1. Opérateur "Alternative"


L'opérateur "alt" désigne un choix, une alternative. Il représente deux comportements possibles : c'est en quelque sorte l'équivalent du SI...ALORS...SINON : donc, une seule des deux branches sera réalisée dans un scénario donné. La condition d'exécution d'une des deux branches (l'équivalent du SI) peut être explicite ou implicite.
L'utilisation de l'opérateur else permet d'indiquer que la branche est exécutée si la condition du alt est fausse.

L'exemple ci-dessous montre un opérateur "alt" : - soit l'utilisateur rentre un code correct et dans ce cas le diagramme de séquence relatif à la vérification du code est appelé, - soit l'utilisateur rentre un code erroné, trois fois, et sa carte est gardée (le distributeur se ré-initialise et demande à nouveau une carte).


1.2. Opérateur "Option"


L'opérateur "opt" désigne un fragment combiné optionnel comme son nom l'indique : c'est à dire qu'il représente un comportement qui peut se produire... ou pas. Un fragment optionnel est équivalent à un fragment "alt" qui ne posséderait pas d'opérande else (qui n'aurait qu'une seule branche). Un fragment optionnel est donc une sorte de SI...ALORS.

L'exemple ci-dessous montre un opérateur "opt" : L'utilisateur, si il est mécontent, peut se défouler sur le distributeur de billets. En revanche, la plupart des utilisateurs contiennent leur agressivité et restent corrects envers le distributeur de billet. L'opérateur "opt" montre cette possibilité.


1.3. Opérateur "Break"


L'opérateur "break" est utilisé dans les fragments combinés qui représentent des scenarii d'exception en quelque sorte. Les intéractions de ce fragment seront exécutées à la place des intéractions décrites en dessous. Il y a donc une notion d'interruption du flot "normal" des intéractions.

L'exemple ci-dessous montre un opérateur "break" : L'utilisateur, lorsque le distributeur lui demande son code, peut choisir de rentrer son code ou de consulter l'aide. Si il choisit de consulter l'aide, le flot d'intéraction relatif à la saisie du code est interrompu. Les intéractions de l'opérateur break sont "exécutées".

L'équivalent de ce diagramme de séquence sans l'opérateur break correspond aux deux diagrammes de séquence ci-après :


1.4. Opérateur "Parallel"


L'opérateur "par" est utilisé pour représenter des intéractions ayant lieu en parallèle. Les intéractions des différents opérandes ( les deux branches de notre opérateur ci-dessous) peuvent donc se mélanger, s'intercaler, dans la mesure où l'ordre imposé dans chaque opérande est respecté.

L'exemple ci-dessous montre un opérateur "par" très simpliste : Un développeur averti ayant accès à Internet peut consulter en parallèle, soit le site http://www.developpez.com soit le site http://www.developpez.net/forums/ sans préférence d'ordre (il peut commencer par consulter les forums puis les cours, soit l'inverse).


Cependant attention! dans tous les entrelacements possibles l'interaction "question" devra toujours apparaître après "consulterSite(" http://www.developpez.net/forums/")" et l'interaction "réponse" devra toujours apparaître après les deux précédentes. Ainsi le cas suivant ne peux pas être un des cas décrit par l'opérateur par ci-dessus :


Au contraire le cas suivant est une illustration du diagramme de séquence :


1.5. Opérateurs "Weak Sequencing" et "Strict Sequencing"


Ces opérateurs sont assez difficiles à comprendre : suit ci-après mon interprétation. La norme ne fournissant pour l'instant pas d'illustration de ces opérateurs, cette interprétation peut ne pas être totalement exacte. N'hésitez pas à me contacter pour m'indiquer votre point de vue.

L'opérateur "Weak Sequencing" se note "seq". Cet opérateur est à opposer à l'opérateur "Strict Sequencing" noté "strict". Ces deux opérateurs font appel à la notion d'ordre des intéractions le long des "lignes de vie" (lifeline).
Un opérateur "seq" notifiera que les intéractions qui s'opèrent entre des entités indépendantes n'ont pas d'ordre particulier. Alors qu'un opérateur "strict" imposera l'ordre décrit sur le diagramme.

La norme indique (traduction personnelle) :
Le "Weak Sequenceing" est défini par un ensemble de traces ayant ces propriétés :
- l'ordre des intéractions présentes dans chaque opérande est maintenu au final,
- les intéractions présentes sur des "lignes de vie" (lifeline) différentes dans des opérandes différents peuvent arriver dans n'importe quel ordre,
- les intéractions présentes sur des "lignes de vie" (lifeline) identiques dans des opérandes différents sont ordonnées de telle manière que les intéractions du premier opérande arriveront avant celles du second opérande.
Donc le "Weak Sequencing" revient à une exécution en parallèle lorsque les participants des opérandes sont disjoints. Le "Weak Sequencing" revient à un "Strict Sequencing" lorsque les opérandes ne font intervenir qu'un seul participant.

Mais plus qu'une explication textuelle sujette à incompréhension, je vous propose deux exemples qui seront sans doute plus clairs.

L'exemple ci-dessous montre un opérateur "seq" : Le "weak sequencing" est le "mode" de description par défaut des diagrammes de séquence. Ici, l'interprétation de ce diagramme est : - resultatMaintenance arrive après actionMaintenance, - question arrive après consulterSite, - reponse arrive après question. Les deux diagrammes ci-dessous sont donc équivalent.



L'exemple ci-dessous montre un opérateur "strict" : Là, l'interprétation de ce diagramme est : - resultatMaintenance arrive après actionMaintenance, - question arrive après consulterSite, - reponse arrive après question. ET - resultatMaintenance arrive apres reponse. Il y a donc un ordre imposé dans cette séquence entre les deux groupes d'intéractions.


1.6. Opérateur "Negative"


L'opérateur "Negative" (négatif) noté "neg" désigne un ensemble d'intéractions invalides.

L'exemple ci-dessous montre un opérateur "neg" : On ne souhaite pas que l'utilisateur puisse obtenir des billets avec un code erroné et une somme demandée incorrecte.


1.7. Opérateur "Critical"


L'opérateur "Critical" (critique) noté "critical" désigne une section critique. Une section critique permet d'indiquer que les intéractions décrites dans cet opérateur ne peuvent pas être interrompues par d'autres intéractions décrites dans le diagramme. On dit que l'opérateur impose un traitement atomique des intéractions qu'il contient.

L'exemple ci-dessous montre un opérateur "critical" : On ne souhaite pas que l'utilisateur puisse obtenir des billets avec un code erroné et une somme demandée incorrecte.


1.8. Opérateurs "Ignore" et "Consider"


L'opérateur "Ignore" (ignorer) indique qu'il existe des messages qui ne sont pas présents dans le fragment combiné. Ces messages sont en fait des messages que l'on peut qualifier d'insignifiants : intuitivement, ce sont des intéractions que l'on ne prend pas en compte. On peut aussi interpréter l'opérateur "ignore" désignant des intéractions pouvant intervenir à tout moment dans le flot des intéractions du diagramme de séquence.
Au contraire, l'opérateur "Consider" (considérer) désigne les interactions à prendre en compte dans la séquence.
On peut imaginer que ce genre de construction soit plus particulièrement utilisé dans des profils orientés tests.

L'exemple ci-dessous montre un exemple pour l'opérateur "ignore" : Le message connexionEtablie est spécifié comme ignorée. On considère que la séquence est tout de même correcte si jamais lors de l'exécution ce message n'apparaissait pas.

L'exemple ci-dessous montre un exemple pour l'opérateur "consider" : Le diagramme ci-dessous est exactement équivalent à celui décrit pour l'opérateur ignore.


1.9. Opérateur "Assertion"


L'opérateur "Assertion" est noté "assert". Il indique que le fragment combiné est une assertion.

Rappel : qu'est-ce qu'une assertion :
Une assertion désigne, selon le Petit Larousse illustré, une proposition que l'on avance et que l'on soutient comme vraie : c'est donc l'équivalent d'une affirmation, la nuance résidant dans le fait (si mes souvenirs sont exacts) que une assertion n'est pas prouvée.

La séquence décrite dans l'opérande désigne donc l'unique séquence possible. Toutes les autres séquences possibles sont des séquences invalides. La norme indique que cette construction est souvent utilisée en combinaison avec les opérateurs "ignore" et "consider". On peut imaginer que ce genre de construction soit plus particulièrement utilisé dans des profils orientés tests.


1.10. Opérateur "Loop"


L'opérateur "Loop" (boucle) est noté "loop". Cet opérateur est utilisé pour décrire un ensemble d'intéraction qui s'exécutent en boucle. En général, une contrainte appelée garde indique le nombre de répétitions (minimum et maximum) ou bien une condition booléenne à respecter.

L'exemple ci-dessous montre un exemple pour l'opérateur "loop" : Le diagramme de séquence indique que lorsque l'utilisateur se trompe trois fois de code, la carte est gardée et le distributeur se remet en mode d'attente d'une carte.


1.10. Combiner les opérateurs


Les fragments combinés et leurs opérateurs peuvent être combinés/mixés en vue de décrire des comportements complexes.

L'exemple ci-dessous montre un exemple de combinaison de fragments : Le diagramme de sequence indique que lorsque l'utilisateur se trompe trois fois de code, la carte est gardée et le distributeur se remet en mode d'attente d'une carte.


2. Les références (appelé en anglais "interaction occurrence")


Une référence (interaction occurrence) peut être vue comme un pointeur ou un raccourci vers un autre diagramme de séquence existant. Cela équivaut à copier le contenu du diagramme de séquence pointé en lieu et place de la référence. Attention cependant à être cohérent au niveau des paramètres utilisés.
Cela permet de factoriser des parties de comportement utilisées dans plusieurs scénarii.

L'exemple ci-dessus montre une référence : Le diagramme de séquence "identifierUtilisateur" fait référence au diagramme de séquence "vérifierSomme" présenté ci-dessous.


3. Les continuations (appelé en anglais "continuation symbol")


Un symbole continuation est un manière de définir des branchements. Ces symboles sont souvent utilisés avec les fragments combinés "alt" : ils permettent ainsi de se brancher sur le bon comportement en fonction de la condition de l'alternative. Dans d'autres langages, ce type de construction est aussi connu sous le nom de label. Les continuations sont représentées par un état qui peut recouvrir plusieurs "lignes de vie"(lifeline).

L'exemple ci-dessous montre l'utilisation du symbole continuation combiné à l'opérateur "alt"


4. Messages Perdus / Trouvés


Deux représentations supplémentaires sont à notre disposition pour la description de scenarii dégradés. Les constructions "perdu / trouvé" (lost and found) permettent de représenter respectivement la perte d'un message (destinataire non contacté) et l'arrivée inopinée d'un message (expéditeur non identifié).

L'exemple ci-dessous montre comment sont représentés des messages perdus / trouvés.


5. Décomposition hiérarchique de diagrammes de séquence (part decomposition)


La décomposition hiérarchique permet de réaliser une description TOP-DOWN du système à réaliser. On peut ainsi commencer par un diagramme de haut niveau ( les utilisateurs + le système) pour chaque fonctionnalité et ensuite raffiner chaque diagramme pour décrire les intéractions entre sous-systèmes.

L'exemple ci-dessous montre le principe relatif à la décomposition hiérarchique. Attention : l'outil utilisé pour réaliser ces exemples ne propose pas encore ce type de construction : cela explique le souligné rouge après le mot clé ref.


6. Création d'objet et suppression


Il est possible de représenter la création d'un objet (équivalent d'un new()) dans un diagramme de séquence : ceci est modélisé au moyen d'une ligne pointillée partant de l'objet père et allant vers l'objet fils.
De même, on peut représenter la mort/suppression d'un objet par une "croix" sur la "ligne de vie". Attention, ce symbole a un caractère définitif, l'objet est considéré comme mort.
On peut donc aisément représenter des créations dynamiques d'objet, des instanciations.



7. Contraintes de temps


Des contraintes temporelles peuvent être indiquées sur les diagrammes de séquence. Le diagramme ci-dessus impose une contrainte de temps pour la connexion d'un utilisateur. Attention, certains outils proposent également la modélisation de timers : les timers ne sont pas spécifiés dans la norme UML2.0 aujourd'hui. C'est donc une construction totalement propriétaire des outils : cela peut poser problème lors des import / export par exemple.



8. Contraintes et invariants


Il est possible d'indiquer les "lignes de vie" des entités des contraintes. Ceci est appelé "state invariant" dans la norme UML2.0. Attention, on parle d'état mais cela peut être tout simplement une valeur d'un attribut.
Cette contrainte est considérée comme évaluée à l'exécution. Elle est évaluée immédiatement avant l'exécution de la prochaine intéraction de telle manière que toutes les actions qui ne sont pas explicitement modelisées soient considérées comme exécutées.
Ces contraintes sont représentées par un état ou par un texte pouvant ressembler à { NomEntite.Attribut1==0}.



Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique UML