Archyno
UMLDiagrammes de comportement

Diagrammes de séquence UML

Le diagramme de comportement que les gens dessinent vraiment. Les participants en haut, le temps qui descend, et chaque message dans l'ordre où il survient - y compris les branches, les boucles et les appels qui échouent.

15 min de lectureUML 2.5.18 sur 35

La réponse courte

  • Un diagramme de séquence répond à : quoi, dans quel ordre, entre qui. Le temps descend, et la distance verticale ne dit rien de la durée.
  • Une pointe de flèche pleine signifie que l'appelant bloque ; une pointe ouverte qu'il poursuit. Cette seule distinction est ce que la notation dit de plus utile sur un système distribué.
  • Conditions et répétitions sont des fragments combinés - alt, opt, loop, par, ref - chacun un cadre avec son opérateur en haut à gauche.
  • Une fois le chemin nominal dessiné, les échecs deviennent dénombrables : pour chaque message, demandez ce qui se passe sans réponse, avec une réponse en erreur, et en cas de double livraison.
Un diagramme de séquence UML. Un marchand soumet un paiement à Checkout, qui demande à l'orchestrateur de paiement de l'autoriser. L'orchestrateur débite la carte via la passerelle et obtient une approbation. À l'intérieur d'un fragment alt, si les fonds sont disponibles il inscrit une écriture au grand livre, sinon il renvoie un refus. Checkout renvoie finalement un reçu au marchand.
Autoriser un paiement. Le temps descend, chaque ligne verticale pointillée est un participant, et la boîte encadrée est un choix entre deux alternatives.

01Ce qu'il montre#

Un diagramme de séquence répond précisément à une question : que se passe-t-il, dans quel ordre, entre qui. C'est le diagramme qu'on trace quand deux personnes ne s'accordent pas sur quel service appelle lequel, ou quand un flux traverse quatre systèmes et que personne n'a le chemin complet en tête.

La mise en page fait tout le travail. Les participants sont alignés en haut. Le temps descend - pas de gauche à droite, et pas à l'échelle. Un message plus bas sur la page se produit après un message plus haut, et c'est toute la règle de lecture.

02Lignes de vie, activations, messages#

Trois meubles, et tout le reste en est une variation.

Une ligne de vie, c'est la tête en haut plus la verticale pointillée qui en descend. La tête nomme le participant. Ce peut être un nom de classe, un objet (: Checkout), un acteur dessiné en bonhomme bâton, ou un rôle avec un stéréotype comme «boundary» ou «control». Quel que soit votre choix, restez cohérent sur tout le diagramme.

Une barre d'activation - parfois appelée occurrence d'exécution - est le rectangle étroit posé sur la ligne de vie. Elle marque la période pendant laquelle ce participant fait quelque chose. Des barres imbriquées signifient qu'un participant s'est rappelé lui-même. Les activations sont optionnelles en UML, et elles valent la peine : elles rendent évident que Checkout attend encore pendant que la passerelle travaille.

Un message est la flèche horizontale. Son style dit de quel type d'appel il s'agit, et c'est la partie à retenir.

03Les types de messages#

ÉlémentNotationCe que cela signifie
SynchroneTrait plein, pointe pleine. L'appelant se bloque jusqu'à la réponse. Une méthode ordinaire ou un appel HTTP bloquant.
AsynchroneTrait plein, pointe ouverte. L'appelant continue immédiatement. Publier dans une file ou émettre un événement.
RéponseTrait pointillé, pointe ouverte. Le retour. Étiquetez-le avec ce qui revient, pas avec le mot « return ».
CreateFlèche pointillée arrivant sur la tête d'une ligne de vie qui commence plus bas. Marquée «create».
Destroyune croix à la fin de la ligne de vieLe participant cesse d'exister ; sa ligne de vie s'arrête à la croix.

La distinction pointe pleine contre pointe ouverte est celle qui pèse vraiment. C'est la différence entre « l'appelant est maintenant bloqué » et « l'appelant est passé à autre chose », et c'est la chose la plus utile qu'un diagramme de séquence dise à un lecteur sur un système distribué.

Un diagramme de séquence UML montrant un appel à soi-même et une création d'objet. L'orchestrateur se valide lui-même, crée ensuite un Receipt par un message create en pointillé, appelle render dessus, et le détruit enfin, ce que marque une croix au bout de sa ligne de vie.
Un auto-appel part et revient sur la même ligne de vie. La tête d'un participant créé descend au message qui le crée, et un participant détruit s'arrête à une croix.

04Se ramifier : les fragments combinés#

Les vrais flux ont des conditions et des répétitions. UML traite les deux avec un fragment combiné : une boîte tracée autour d'une suite de messages, avec un opérateur dans une étiquette en haut à gauche.

  • alt - alternatives. Séparé par un trait pointillé en compartiments, chacun avec une garde entre crochets. Exactement un s'exécute. C'est un si/sinon.
  • opt - optionnel. Un compartiment avec une garde ; il s'exécute ou non. C'est un si sans sinon.
  • loop - répétition. La garde donne la condition ou les bornes, comme loop [1..*] ou loop [tant qu'il reste des pages].
  • par - parallèle. Les compartiments s'exécutent concurremment, sans ordre garanti.
  • ref - une référence à une interaction définie sur un autre diagramme. C'est ainsi qu'on empêche un diagramme de séquence de s'étaler sur trois pages.
  • critical - une région qui ne doit être entrelacée avec rien d'autre.

05Le cadre, les portes et les messages venus de nulle part#

Tout ce qui précède se trouve dans une boîte que la plupart des diagrammes tracent et que peu de lecteurs remarquent : le cadre d'interaction, un rectangle autour du diagramme entier avec une étiquette en haut à gauche portant sd et le nom de l'interaction. Cela ressemble à de la décoration et n'en est pas : c'est ce qui donne un nom à l'interaction, et c'est le nom qui rend ref possible. Sans lui, impossible de découper un flux long, ce qui veut dire que chaque flux doit tenir sur une page.

ÉlémentNotationCe que cela signifie
Cadresd AuthorizePaymentLa boîte autour du diagramme et le nom de l'interaction dedans. Ce que vise un ref sur un autre diagramme.
Porte (gate)une flèche se terminant sur le cadreUn message qui franchit la frontière du cadre au lieu de commencer ou finir sur une ligne de vie. C'est la liste de paramètres de l'interaction : c'est ainsi qu'un ref reçoit et renvoie quoi que ce soit.
Message trouvéun cercle plein à la baseArrive d'un émetteur que le diagramme ne modélise pas - un clic, un ordonnanceur, un webhook. Honnête, et bien meilleur qu'inventer une ligne de vie pour le monde extérieur.
Message perduun cercle plein à la pointeEnvoyé à un destinataire que le diagramme ne modélise pas, ou qui n'arrive réellement jamais. Rare sur un diagramme de conception, utile sur un diagramme décrivant une panne.
Contrainte de durée{ < 200ms }Une contrainte entre accolades couvrant deux points d'une ligne de vie. Le seul moyen pour un diagramme de séquence de dire quoi que ce soit sur le temps, puisque la distance verticale ne dit rien.
Invariant d'état{ order = PLACED }Une condition écrite sur une ligne de vie qui doit tenir à cet endroit. Utile juste au-dessus d'un message dont toute la raison d'être est cette condition.

La liste de fragments de la section précédente est l'ensemble de travail, pas l'ensemble complet. Quatre autres opérateurs existent et trois méritent parfois leur place : break abandonne le reste du fragment englobant quand sa garde tient, ce qui est la forme naturelle d'un retour anticipé sur erreur ; strict impose l'ordre de ses compartiments là où seq les laisse libres ; neg marque une interaction qui ne doit pas se produire, une façon d'inscrire un test négatif dans une image. assert, ignore et consider relèvent de la spécification formelle et peuvent être ignorés jusqu'à ce que quelque chose vous les impose.

06En extraire les chemins d'échec#

Ce qu'un diagramme de séquence a de plus précieux n'est pas de documenter le chemin heureux. C'est qu'une fois le chemin heureux sur la page, les échecs deviennent dénombrables - et un flux traversant quatre systèmes en a bien plus que quiconque n'estime de mémoire.

Descendez le diagramme et posez trois questions à chaque message, dans cet ordre. Les réponses sont vos chemins d'extension, et chacune est soit un fragment à tracer, soit une décision que quelqu'un doit prendre.

  1. Et s'il n'y a pas de réponse ? Chaque message synchrone est un endroit où l'appelant peut se bloquer indéfiniment. Il existe quelque part une valeur de délai ; si personne dans la salle ne la connaît, c'est là le constat. Tracez-le en alt avec une garde [timeout], et le chiffre se retrouve sur le diagramme où l'on peut en discuter.
  2. Et si la réponse est un échec ? Distinct de l'absence de réponse, et traité de façon identique par une quantité inquiétante de code de production. Une autorisation refusée et un acquéreur mort demandent des traitements différents, et c'est sur le diagramme que cette différence devient visible.
  3. Et si ceci est livré deux fois ? Posez la question à chaque message asynchrone, car les files redélivrent et les clients réessaient. Si la réponse est « le client est débité deux fois », vous venez de trouver l'exigence d'idempotence qui n'était pas dans le ticket.

Relisez ensuite le diagramme à l'envers, pour la question que la passe avant ne capture jamais : qu'est-ce qui s'est déjà produit et doit maintenant être défait ? Un échec au quatrième message laisse en place les effets des trois premiers. C'est la logique de compensation, et un diagramme de séquence est l'endroit le moins cher au monde pour découvrir qu'il vous en faut.

07Quand en tracer un#

À utiliser quand

  • Un flux traverse plusieurs services et l'ordre des appels n'est pas évident
  • Il faut trancher un désaccord sur qui est responsable d'appeler qui
  • Documenter un protocole, une poignée de main ou une intégration pour une autre équipe
  • Trouver où sont les modes de défaillance - le diagramme rend visibles les chemins d'erreur manquants

Préférer autre chose quand

  • L'interaction, c'est deux participants et trois messages - écrivez la phrase
  • Vous vous intéressez au temps écoulé ou aux délais - prenez un diagramme de temps
  • La question est la structure, pas l'ordre - prenez un diagramme de classes ou de composants
  • Le flux est surtout de la logique de branchement - un diagramme d'activité sera bien plus lisible

Le diagramme de séquence est aussi l'artefact UML le plus efficace pour relire une conception avant de la construire, parce qu'il force les questions gênantes au grand jour. Que se passe-t-il si la passerelle expire ? Qui réessaie ? Cet appel est-il bloquant ? On ne peut pas tracer le diagramme sans y répondre.

08Erreurs courantes#

  1. Toutes les flèches en trait plein et pointe pleine. Si tout paraît synchrone, le diagramme a jeté sa distinction la plus utile. Pointes ouvertes pour le tire-et-oublie.
  2. Des flèches de réponse partout. La réponse à un appel synchrone est souvent implicite et peut être omise. Tracez-la quand la valeur renvoyée compte.
  3. Mélanger les niveaux d'abstraction. Une ligne de vie pour toute une plateforme de paiement à côté d'une ligne de vie pour une classe utilitaire. Choisissez une altitude.
  4. Aucun chemin d'erreur. Le chemin heureux seul est la moitié la moins intéressante. C'est l'alt avec la branche de délai qui rend le diagramme digne d'être relu.
  5. Vingt lignes de vie. Au-delà de sept environ, le diagramme ne tient plus à l'écran et se fait faire défiler plutôt que lire. Découpez-le et utilisez ref.

En une ligne chacun

  1. 01Les participants en haut, le temps vers le bas ; la distance verticale n'est pas une durée.
  2. 02Pointe pleine : synchrone et bloquant. Pointe ouverte : asynchrone.
  3. 03Les flèches pointillées sont des réponses ; pointillée vers une tête abaissée, c'est «create».
  4. 04Les barres d'activation montrent qui est occupé, et elles valent l'effort.
  5. 05alt, opt, loop, par et ref couvrent le branchement ; jamais plus de deux niveaux d'imbrication.
  6. 06Tracez le chemin d'échec - c'est la moitié qui rend le diagramme utile.

09Questions fréquentes#

Qu'est-ce qu'une ligne de vie dans un diagramme de séquence ?

La ligne verticale pointillée sous chaque participant, qui représente son existence dans le temps. Le temps descend, donc un message tracé plus bas survient après un message situé au-dessus.

Quelle est la différence entre message synchrone et asynchrone ?

Un message synchrone porte une pointe pleine et signifie que l'émetteur attend le retour de l'appel. Un message asynchrone porte une pointe ouverte et signifie que l'émetteur continue aussitôt. La réponse à un appel synchrone est une ligne pointillée à pointe ouverte.

Que veulent dire alt, opt, loop et par ?

Ce sont des fragments combinés : des cadres étiquetés autour d'une portion de l'interaction. alt est un branchement à gardes, opt une branche unique qui peut ne pas s'exécuter, loop répète son contenu, et par signifie que ses régions peuvent s'entrelacer. L'étiquette occupe le pentagone en haut à gauche.

Qu'est-ce qu'une barre d'activation ?

Le rectangle étroit tracé sur une ligne de vie pendant que le participant travaille, formellement une spécification d'exécution. Elle commence à la réception d'un message et finit au retour, ce qui rend les appels imbriqués visibles sous forme de barres empilées.

Quand préférer un diagramme de séquence à un diagramme de communication ?

La séquence quand l'ordre des messages est le sujet : un protocole, un chemin d'échec, un délai dépassé. La communication quand la structure est le sujet, c'est-à-dire qui est relié à qui. Les deux portent la même information et ne diffèrent que par la mise en page.

Dans cette série

À lire aussi

Tous les articles