5  Diagrammes de séquence système (DSS)

Un diagramme de séquence système (DSS) est un diagramme UML (diagramme de séquence) limité à un acteur (provenant du scénario d’un cas d’utilisation) et au Système. Les DSS sont expliqués en détail dans le chapitre 10 , mais voici des points importants pour la méthodologie de ce manuel :

5.1 Exemple : DSS pour Attaquer un pays

La figure 5.1 est un exemple de DSS pour le cas d’utilisation Attaquer un pays. Vous pouvez noter tous les détails (titre, arguments, types).

:Joueur:SystèmedémarrerAttaque(paysAttaquant : String,paysDéfenseur : String)loop[pas terminé]annoncerAttaque(nbRégimentsAttaquant : int)annoncerDéfense(nbRégimentsDéfenseur : int)résultats des deux lancers, régiments perdusde l'attaquant et du défenseur le cas échéantterminerAttaque()

Figure 5.1: Diagramme de séquence système pour Attaquer un pays. (PlantUML)

5.2 Les DSS font abstraction de la couche présentation

Le but du DSS est de se concentrer sur l’API (les opérations système) de la solution. Dans ce sens, c’est une conception de haut niveau. Le « Système » est modélisé comme une boîte noire. Par exemple, dans la figure 5.2, il y a l’acteur, le Système et une opération système. On ne rentre pas dans les détails, bien qu’ils existent et soient importants.

:Joueur:SystèmedémarrerAttaque(...)

Figure 5.2: Une opération système dans un DSS. C’est une abstraction. (PlantUML)

Plus tard, lorsque c’est le moment d’implémenter le code, les détails importants seront à respecter. Il faut faire attention aux principes de la séparation des couches présentation et domaine. Par exemple, la figure 5.3 rentre dans les détails de ce qui se passe réellement dans une opération système quand la solution fonctionne avec un service Web :

  • D’abord, l’acteur clique sur un bouton ;
  • Ce clic se transforme en service REST ;
  • Un routeur transforme l’appel REST en une opération système envoyée à un contrôleur GRASP. Notez que c’est un objet du domaine qui reçoit l’opération système – c’est l’essence du principe GRASP Contrôleur ;
  • Le contrôleur GRASP dirige la suite, selon la solution proposée dans la réalisation de cas d’utilisation (RDCU).

Couche présentationCouche domaine:Joueur«NavigateurWeb»:Button«NodeExpress»:Routeur«ContrôleurGRASP»:JeuRisk...cliquerHTTP GET/api/v1/démarrerAttaque/...Router handler (Express)démarrerAttaqueOpération système définie dans DSSdémarrerAttaque(...)...selon la RDCU

Figure 5.3: Une opération système est envoyée par la couche présentation et elle est reçue dans la couche domaine par son contrôleur GRASP. Ceci est un exemple avec un navigateur Web, mais d’autres possibilités existent pour la couche présentation. (PlantUML)

La figure 5.3 est à titre d’information seulement. Un DSS ne rentre pas dans tous ces détails.

5.3 FAQ DSS

5.3.1 Faut-il une opération système après une boucle ?

Dans l’exemple pour Attaquer un pays, à l’extérieur de la boucle, il y a une opération système terminerAttaque. Est-ce obligatoire d’avoir une opération système après une boucle ?

L’opération système terminerAttaque sert à signaler la fin de la boucle. Le système saura que l’acteur ne veut plus répéter les actions dans la boucle. Mais elle permet aussi de faire des calculs concernant ce qui s’est passé dans la boucle, par exemple pour déterminer qui contrôle quel pays après les attaques.

Cependant, si vous avez une boucle pour indiquer la possibilité de répéter une action (par exemple ajouter des produits dans un système d’inventaire) et que vous n’avez pas besoin de faire un calcul à la fin, alors une opération système pour terminer une telle boucle n’est pas nécessaire (surtout avec une application Web).

5.3.2 Comment faire si un cas d’utilisation a des scénarios alternatifs ?

Fait-on plusieurs DSS (un pour chaque scénario) ou utilise-t-on la notation UML (des blocs opt et alt) pour montrer des flots différents dans le même DSS ?

Un objectif derrière le DSS est de définir les opérations système. Donc, on peut se poser la question suivante : les scénarios alternatifs impliquent-ils une ou plusieurs opérations système n’ayant pas encore été définies ? Si la réponse est non, on peut ignorer les scénarios alternatifs dans le DSS. Par contre, si la réponse est oui, il est essentiel de définir ces opérations système dans un DSS. Quant au choix de faire des DSS séparés ou d’utiliser la notation UML pour montrer les flots différents sur le même DSS, ça dépend de la complexité de la logique des flots. Un DSS devrait être facile à comprendre. C’est à vous de juger si votre DSS avec des opt ou des alt est assez simple ou fait du spaghetti. Utilisez un autre DSS (ou plusieurs) ayant le nom des scénarios alternatifs si cela vous semble plus clair.

5.3.3 Est-ce normal d’avoir une opération système avec beaucoup d’arguments (de type primitif) ?

Puisqu’une opération système doit avoir seulement des arguments de type primitif, j’ai plusieurs opérations système avec de nombreux (plus que 5) arguments. Pourquoi n’est-il pas permis de passer des objets comme arguments ?

Il n’est pas conseillé de passer des objets du domaine comme arguments, puisque c’est la couche présentation qui invoque l’opération système. La couche présentation n’est pas censée manipuler directement les objets dans la couche domaine, sinon elle empiète sur les responsabilités de la couche domaine.

Une solution pour réduire le nombre d’arguments sans utiliser un objet du domaine est d’appliquer un réusinage pour le smell nommé Long Parameter List, par exemple Introduce Parameter Object. Notez que l’objet de paramètre que vous introduisez n’est pas un objet (classe) du domaine ! La distinction est importante, car la logique d’affaires demeure dans la couche domaine. En TypeScript, une fonction peut être définie avec un objet de paramètre. Cet exemple montre même comment on peut « déstructurer » l’objet pour déclarer les variables utilisées dans la fonction :

// inspiré de https://leanpub.com/essentialtypescript/read
function compteARebours({ initial: number, final: final = 0,
                          increment: increment = 1, initial: actuel }) {
    while (actuel >= final) {
        console.log(actuel);
        actuel -= increment
    }
}
compteARebours({ initial: 20 });
compteARebours({ initial: 20, increment: 2, final: 4 });

5.3.4 Ne serait-il pas plus simple de passer l’objet body de la page Web au contrôleur GRASP ?

Décortiquer toutes les informations dans un formulaire Web est compliqué, puis on doit passer tout ça à un contrôleur GRASP comme des arguments de type primitif. Ne serait-il pas plus simple de passer l’objet body de la page Web au contrôleur GRASP et de le laisser faire le décorticage ?

Dans un sens, ça serait plus simple (pour le code de la couche présentation). Cependant, on veut séparer les couches pour favoriser le remplacement de la couche présentation, par exemple à travers une application iOS ou Android.

Si vous mettez la logique de la couche présentation (décortiquer un formulaire Web) dans la couche domaine (le contrôleur GRASP), ça ne respecte pas les responsabilités des couches. Imaginez un tel contrôleur GRASP si vous aviez trois types d’applications frontales (navigateur Web, application iOS et application Android). Le contrôleur GRASP recevra des représentations de « formulaire » de chaque couche présentation différente. En passant, l’objet body n’a rien à voir avec une interface Android ! Ce pauvre contrôleur serait alors obligé de connaître toutes les trois formes (Web, iOS, Android) et, ainsi, sa cohésion serait beaucoup plus faible. Pour respecter les responsabilités, on laisse la couche présentation faire le décorticage et construire une opération système selon l’API définie dans le DSS. Cela simplifie aussi le contrôleur GRASP.

5.4 Exercices

Note

Vous pouvez dessiner les diagrammes à la main et en prendre une photo avec une application comme Microsoft Lens (Android, iOS).

Vous pouvez également utiliser PlantUML. Voici des ressources à ce propos :

Méfiez-vous des outils comme Lucidchart ayant seulement des profils superficiels pour UML (voir la figure 13.5).

Exercice 5.1 (Dessiner un DSS à partir d’un cas d’utilisation) Esquissez le DSS pour le cas d’utilisation Réserver un livre de la bibliothèque. Toutes les opérations système doivent définir le type de chaque argument, le cas échéant.