Ajouter un segment de choix
Souvent dans les machines d’état, vous devez effectuer une transition d’état uniquement lorsqu’une condition spécifique (appelée condition de garde) est évaluée à TRUE au moment de l’exécution. De plus, très souvent, vous devez passer à différents états, en fonction du résultat de certaines conditions de garde évaluées au moment de l’exécution.
L’UML fournit une construction spéciale, appelée “pseudostate de choix”, que vous pouvez utiliser dans de telles situations. Un “pseudostate de choix” vous permet de diviser une transition en plusieurs chemins sortants, chacun avec sa propre condition de garde.
Notez qu’il est utile de considérer le pseudostate de choix, tel que celui montré dans le panneau (B) du diagramme ci-dessus, comme l’instruction compoundif (guard1()) {...} else if (guard2()) {...}
(c’est en fait ainsi que le générateur de code QM™ implémente les segments de choix). Attention, car les gardes conduisent àIF
s etELSE
s dans le code, leur utilisation excessive conduit à du code “spaghetti” et va à l’encontre de l’objectif d’utiliser des machines d’état en premier lieu. Pour cette raison, les gardes doivent être utilisés judicieusement.
Dans la plupart des outils UML, le processus de dessin des segments de choix consiste à ajouter d’abord un “pseudostate de choix” (diamant), puis à attacher un segment de transition sortant avec une protection. Dans QM™, ce processus est simplifié, car la boîte à outils State Machine contient un outil de segment de choix prêt à l’emploi, qui combine un “pseudostate de choix” avec un segment de transition qui lui est attaché de manière permanente.
Remarque Le segment de choix est le seul moyen dans QM ™ d’attacher une condition de garde à une transition, comme illustré dans le panneau (A) du diagramme ci-dessus. Mais le segment QM™ Choice est plus puissant que de simples protections sur les transitions, comme expliqué dans les sections suivantes. Remarque Pour ajouter un segment de choix, vous devez d’abord créer et afficher un diagramme d’état. De plus, la machine d’états doit avoir au moins une transition interne (terminée par) ou un segment de choix(). Enfin, pour ajouter, déplacer, redimensionner ou modifier des segments de choix, le diagramme de la machine d’état doit être déverrouillé().
Assurez-vous que la sous-fenêtre de la machine d’état est active. Dans la boîte à outils State Machine, cliquez sur l’outil Choice Segment et relâchez le bouton de la souris (ne faites pas glisser l’outil hors de la barre d’outils). À ce stade, lorsque vous passez la souris sur le diagramme d’état actif, le pointeur de la souris passe à l’outil segment de choix avec l’icône “interdit” (), car un segment de choix ne peut être ajouté qu’à une extrémité carrée non attachée d’une transition () ou à un segment de choix existant (). Lorsque vous passez la souris sur un point de fixation autorisé pour un segment de choix, le pointeur de la souris passe à l’outil segment de choix avec l’ancre (). Pour ajouter le segment de choix à ce point de fixation, appuyez sur le bouton de la souris et faites glisser l’extrémité du segment de choix vers le bord souhaité de l’état cible. Le chemin de transition ainsi établi correspondra à une transition régulière d’état à état avec une garde.
Vous pouvez également ajouter un segment de choix qui deviendra une transition interne avec un garde. Pour ce faire, il vous suffit de faire glisser la fin du segment de choix et de ne le déposer sur aucun bord d’état. À ce stade, le segment de choix deviendra une transition interne. La transition interne est entièrement exécutée dans l’état source et ne conduit jamais à un changement d’état.
Remarque La notation UML “normative” standard ne vous permet pas d’ajouter des segments de transition internes à des pseudostats de choix. En revanche, la représentation non normative des transitions internes dans QM ™ vous permet d’ajouter facilement des segments de transition internes à des pseudostats de choix et de changer rapidement et intuitivement le type de transition en attachant / détachant l’extrémité de transition vers / depuis un état.
Enfin, vous pouvez également ajouter un segment de choix à une extrémité non attachée d’un autre segment de choix, comme illustré dans l’animation ci-dessous:
Remarque Cette option d’ajout de Segments de Choix à des segments de choix déjà existants signifie que vous pouvez créer des gardes imbriqués complexes. Cependant, comme pour toutes les conditions de garde, vous devez utiliser cette fonctionnalité judicieusement pour éviter le code “spaghetti”.
L’élément de segment de choix peut être configuré par la feuille de propriétés spécifique au choix.
La feuille de propriétés Choice Segment contient les propriétés suivantes:
- Choice Guard
- Cible de choix (non modifiable – déterminée géométriquement)
- Action de choix
Choice Guard
Chaque segment de choix dans QM™ doit avoir une propriété de garde explicite, qui se compose de deux entrées : pseudocode et code. Seule l’entrée de code de la propriété guard est pertinente pour la génération de code. L’entrée pseudocode est conçue uniquement pour être affichée dans le diagramme afin d’éviter l’encombrement en minimisant la quantité de texte à afficher à côté de la forme de transition.
Attention L’entrée Pseudocode de la propriété guard est uniquement destinée à être affichée dans la Zone de texte associée au segment choice, mais elle n’a aucune incidence sur la génération de code. Remarque La propriété guard est affichée dans la Zone de texte du segment choice selon les mêmes règles que la Zone de texte de transition. De plus, pour réduire l’encombrement dans le diagramme, la garde est affichée sous une forme abrégée, où tous les espaces dans la garde sont supprimés et le texte de garde résultant est tronqué à 32 caractères. (Lorsque la garde est tronquée, le dernier caractère est ‘~’).
Pour une génération de code réussie, l’entrée de code de la propriété guard doit être une expression booléenne C ou C++ légale. L’expression peut utiliser les attributs de la machine d’état (via le pointeur me) et les paramètres d’événement de l’événement déclencheur (voir section ci-dessous).
Accès à l’événement Déclencheur: L’expression de garde peut accéder à l’événement déclencheur d’origine (de la transition à laquelle le choix est attaché directement ou indirectement), qui est fourni comme le pointeur e du type (QEvt const * const)
. Cela signifie que vous avez un accès en lecture seule à l’événement et que vous ne pouvez pas modifier le pointeur e
. Pour accéder aux paramètres d’événement de l’événement déclencheur d’origine, vous devez généralement réduire le pointeur d’événement e. Ce downcast est toujours basé sur le déclencheur de transition (signal de l’événement déclencheur, voir Déclencheur de transition), ce qui signifie que vous devez toujours connaître le type d’événement (classe d’événement) associé au déclencheur.
Cible de choix
La propriété target n’est pas modifiable directement, mais elle est déterminée géométriquement par le point final du segment de choix. Pour les transitions d’état à état, la propriété target répertorie l’état cible auquel le point final() se termine. Pour les transitions internes avec le point final carré(), la propriété target affiche internal
.
Action de choix
Un segment de choix peut avoir une propriété d’action facultative, qui n’est exécutée que lorsque la garde est évaluée à TRUE au moment de l’exécution (voir également Évaluation de l’ordre d’action).
La propriété action se compose de deux entrées : pseudocode et code (voir Feuille de propriétés Choice). Seule la partie code de la propriété action est pertinente pour la génération de code. Le champ pseudocode est conçu uniquement pour être affiché dans le diagramme afin d’éviter l’encombrement en minimisant la quantité de texte à afficher à côté de la forme de transition.
Remarque L’entrée Pseudocode de la propriété action est uniquement destinée à être affichée dans le diagramme et n’a aucune incidence sur la génération de code. Pointeur
vers l’Événement déclencheur: Le code d’action de choix doit souvent accéder à l’événement déclencheur, qui est fourni comme pointeur e du type (QEvt const * const)
. Cela signifie que vous avez un accès en lecture seule à l’événement et que vous ne pouvez pas modifier le pointeur e
. Pour accéder aux paramètres d’événement de l’événement déclencheur, vous devez généralement réduire le pointeur d’événement e. Ce downcast est toujours basé sur le déclencheur de transition (signal de l’événement déclencheur, voir Déclencheur de transition), ce qui signifie que vous devez toujours connaître le type d’événement (classe d’événement) associé au déclencheur.
Zone de texte de choix
Une fois que l’élément de segment de choix est sélectionné comme Élément actuel, vous pouvez voir la limite de la Zone de texte associée au segment de choix. La Zone de texte vous permet de déplacer et de redimensionner le texte de choix en le faisant glisser ou en faisant glisser la Poignée de la Zone de texte selon le même algorithme que la Zone de texte de transition.
La garde else
La propriété guard peut être définie comme le mot clé else spécial. Une telle autre garde complète toutes les autres conditions de garde attachées au même pseudo-état de choix. La garde else peut être spécifiée dans l’entrée de code ou l’entrée de pseudocode de la propriété guard. De toute évidence, la garde “else” n’a de sens que pour un pseudostate de choix avec plusieurs segments de choix sortants.
Remarque Lors de la génération de code, la garde else sera toujours générée en dernier dans le groupe de toutes les gardes associées au même pseudo-état de choix, quel que soit son ordre dans l’Explorateur de modèles.
Segments de choix Sans autre
Selon la spécification UML, un événement qui ne peut pas être traité en raison de l’évaluation de tous les gardes à FALSE doit être traité comme non traité, ce qui signifie qu’il doit être propagé au(x) super-état (s). Cette exigence a des implications pour les pseudostats de choix sans segment else explicite. Plus précisément, pour se conformer à la sémantique UML, le générateur de code QM™ générera dans de tels cas une branche else
implicite qui provoquera la propagation de l’événement vers le ou les super-États.
Notez qu’il existe une différence entre un pseudostate de choix avec un segment else vide et un pseudostate de choix par ailleurs identique sans le segment else. L’else vide explicite entraînera la consommation de l’événement (sans rien faire), tandis que l’absence du segment else entraînera la propagation de l’événement au(x) super-état (s).
Évaluation de l’Ordre de garde
La spécification UML exige que les conditions de garde attachées au même pseudo-état de choix soient complémentaires, de sorte que l’ordre d’évaluation des gardes n’a pas d’importance. Bien que la complémentarité des gardes soit toujours recommandée dans QM™, l’outil évalue les gardes toujours dans l’ordre prédéterminé, sur lequel vous pouvez compter.
L’ordre d’évaluation de la garde est déterminé par l’ordre des éléments de segment de choix dans l’Explorateur de modèles. Cet ordre peut être modifié à l’aide des boutons Haut et Bas de la barre d’outils de l’Explorateur. Alternativement, l’élément en cours peut être déplacé vers le haut ou vers le bas dans l’Explorateur de modèles au moyen des raccourcis clavier: Ctrl- (touche montante) et Ctrl- (touche descendante).
Remarque En cas de chevauchement des gardes lorsque l’ordre d’évaluation des gardes est important, il est fortement recommandé d’organiser graphiquement les Segments de choix dans le diagramme dans le même ordre que dans l’Explorateur de modèles, comme illustré dans la capture d’écran ci-dessus. Le code généré suivra alors le même ordre, comme indiqué à droite du diagramme ci-dessus.
Évaluation de l’ordre d’action
Tous les segments de choix attachés à une transition ajoutent les actions de segment de choix à l’action effectuée par la transition. L’ordre d’évaluation de toutes ces actions est intuitif et commence toujours par l’action de transition exécutée inconditionnellement, suivie de l’évaluation conditionnelle des actions de segment de choix.
Par exemple, l’évaluation de l’ordre d’action dans le diagramme ci-dessus est résumée par le pseudocode suivant:
Segments de Choix imbriqués
Comme décrit ci-dessus, les Segments de choix peuvent s’imbriquer. Cela vous permet de créer des chemins de transition conditionnels complexes, mais comme toujours avec les gardes, la fonctionnalité ne doit pas être surutilisée.
Par exemple, une erreur courante consiste à utiliser des segments de choix profondément imbriqués pour choisir parmi un certain nombre de chemins de transition possibles (voir le panneau (A) dans le diagramme ci-dessous):
Une alternative meilleure et beaucoup plus simple consiste à utiliser des segments à choix multiples attachés au même pseudostat de choix, comme indiqué dans le panneau (B) du diagramme ci-dessus.
Remarque N’oubliez pas que vous pouvez attacher de nombreux segments de choix à une transition donnée. Un diagramme avec un plus petit nombre de pseudostats de choix (diamants) est un diagramme meilleur et plus facile à comprendre. Attention Le générateur de code QM™ limite le nombre de niveaux d’imbrication dans le code à 16 (y compris l’imbrication dans les fonctions de gestionnaire d’état). L’utilisation de segments de choix profondément imbriqués peut facilement dépasser cette limite.
Segments de choix de routage
Une transition avec des segments à choix multiples, dont certains sont potentiellement imbriqués, regroupe de nombreux éléments dans un petit espace de diagramme. Pour réorganiser graphiquement une “boule de connecteurs” aussi complexe, vous devez connaître les règles de base qui s’appliquent dans cette situation.
La première règle est qu’avant de pouvoir modifier la forme d’un élément, vous devez d’abord le sélectionner.
Par exemple, si vous souhaitez déplacer le pseudo-état de choix (le diamant), vous devez cliquer sur la transition entrante d’origine vers le pseudo-état de choix. Veuillez noter que vous ne devez pas cliquer spécifiquement sur la forme de diamant elle-même, car il s’agit en fait d’une collection chevauchée de la fin de transion entrante et de tous les segments de choce sortants, il est donc ambigu de savoir quelle forme vous voulez réellement dire. Au lieu de cela, vous devez cliquer sur l’un des segments de transition ou le début-fin du transiton. (REMARQUE : Vous pouvez également sélectionner sans ambiguïté n’importe quel élément de modèle dans la vue Explorateur de modèles). L’animation suivante illustre le processus:
D’autre part, si vous sélectionnez un segment de choix sortant, vous ne pouvez pas déplacer le pseudostate de choix. Au lieu de cela, vous pouvez maintenant déplacer uniquement le segment de choix sélectionné pour le rattacher ailleurs.
Leave a Reply