Title: Langage de Spcification d'Interfaces Spcifications des IHM l'aide d'tats
1Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
- A l'attention des étudiants de
- l'ESIL-Info.
- Auteur Laurent Henocque
- mis à jour en Février 2008
2Licence Creative Commons
- Cette création est mise à disposition selon le
Contrat Paternité-Partage des Conditions
Initiales à l'Identique 2.0 France disponible en
ligne - http//creativecommons.org/licenses/by-sa/2.0/fr/
- ou par courrier postal à Creative Commons, 559
Nathan Abbott Way, Stanford, California 94305,
USA.
3Situation
- Aucun langage dédié n'existe pour la
spécification homme machine - Les interfaces homme machine sont essentiellement
spécifiées par prototypage - Cette approche n'offre aucun secours dans le cas
de grands projets comportant des dizaines ou des
centaines d'écrans - Il existe un réel besoin de support pour la
spécification des IHM
4Cas du Prototypage
- Un prototype peut être présenté au client et
validé. - Le prototype montre que ce qui est développé est
compatible avec le besoin - Le prototype ne peut pas illustrer des OBJECTIFS
de développement - d'ergonomie notamment. - Il manque alors un langage pour décrire CE QUE
l'on veut implanter, avant de le faire
effectivement.
5Rendre une spécification d'IHM exécutable
- Il est possible de développer une bibliothèque
logicielle permettant de rendre exécutables des
spécifications d'états - Cela a été réalisé deux fois au moins dans le
produit Ilog Views, après un premier projet
appelé Open Side - Open Side (1991) le langage des contextes,
intégré au langage WIZ. - Ilog Views (1995) intégration d'une API de
gestion d'états dans l'outil ILOG Views - Aujourdhui JavaStates
6ISL
- ISL Interface State Language
- un langage pour décrire la dynamique des
interfaces homme machine. - ISL est fondé sur une extension du langage de
spécification d'états défini par la méthode UML - ISL peut être rendu exécutable - mais peut être
utilisé comme un langage
7La dynamique "interne" des IHM
- ISL décrit la dynamique interne des interfaces
- Les actions et changements qui n'appellent pas
des fonctions externes, mais sont limitées à
l'interface elle même - Par exemple, une interface cache ou dévoile
fréquemment des fenêtres, change l'aspect de
boutons, positionne ou enlève des callbacks sur
des objets
8Transitions
- En ISL, une interface est décrite par ses états
possibles - La dynamique interne est définie par des
changements d'états, appelés transitions - Ces transitions d'état sont causées par des
callbacks appliqués statiquement aux objets de
l'interface - La fraction de la dynamique de l'interface qui
relève de changements d'états est ainsi décrite
de façon statique
9Bénéfices attendus
- la spécification exacte de l'interface, en
garantissant l'absence de défauts d'aspects - le support d'abstractions utiles lors de projets
réalisés en équipe - accroître la dynamique et les qualités
ergonomiques d'une interface à moindre coût - automatiser l'automate d'interfaces très complexes
10Brève introduction aux diagrammes d'état de UML
11Interfaces et Etats
- Les interfaces graphiques, et plus généralement
toutes les sortes d'interfaces homme machine sont
bien décrites autour de la notion d'état - On peut laisser son ordinateur allumé pendant des
semaines et espérer le retrouver dans le même
état en revenant - Par contre, la prise en compte d'une entrée sera
en apparence instantanée dans la plupart des cas
12UML
- http//www.sparxsystems.com.au/resources/uml2_tuto
rial/uml2_statediagram.html - Object Management Group (OMG)
http//www.omg.org - OMG UML Resource Page http//www.omg.org/technolo
gy/uml - Object Mentor Inc. - information on UML Design
Principles http//www.objectmentor.com - UML Forum - Public forum for the UML modeling
community http//www.uml-forum.com
13Etats - Evénements - Transitions
- l'entrée est appelée un événement
- le changement d'état en réponse à un événement
est une transition - l'événement comme le changement d'état sont
réputés avoir une durée nulle ou négligeable,
mais un état peut durer indéfiniment
14Etat composite à deux sous états
15Etats élémentaires
16Pseudo états
17Concurrence
18Points d'entrée et de sortie
19Automate à Protocole
20Pré et post conditions dans les protocoles
21Points d'entrée/sortie dans les composites
22Jonctions
23Décisions
24Self Transitions
25Composite caché
26Exemples de régions
27Exemple de sous diagramme
28Exemple
29Variante
30Exemple
31Invariant d'état
32Exemple du téléphone
33Exemple
34Exemple avec extension
35Exercices
- Dessiner le diagramme détats de lautomate dun
bouton dans une IHM - Dessiner le diagramme détats de lautomate dune
application de type éditeur de texte
36Concepts fondateurs de ISL
37Descripteur d'état
- ISL permet de nommer les états d'une interface,
et ainsi de définir explicitement l'automate
d'états finis que l'interface réalise - A chaque état sont associés autant de
descripteurs que nécessaire - Un descripteur est la spécification d'une
certaine ressource graphique (couleur, position,
visibilité...) où de comportement (callback,
réponse à un événement) pour un objet donné
38Détection VS Sélection d'état
- ISL ne requiert pas de détecter dans quel état se
trouve une interface, mais permet de définir un
état courant - if / switch - case etc...
- Tous les descripteurs d'un état sont pris en
compte lorsque cet état est sélectionné, et donc
les changements correspondants effectués - analogue dynamique des classes et des fonctions
virtuelles
39Implantation des transitions
- Une implantation d'ISL peut effectuer des calculs
une fois pour toutes lorsqu'un état donné est
sélectionné. Par la suite, aucun programme ne
devra tester dans quel état l'interface se trouve - En reposant sur une implantation de ISL, une
interface ne teste jamais si elle se trouve dans
un état compatible avec la gestion d'un
événement, et ne teste pas non plus quelle est la
transition appropriée - La transition appropriée a été installée sous
forme d'un callback adéquat lors du changement
d'état
40Descripteurs de transitions
- Parmi les descripteurs dynamiques figurent
"setState" et "leaveState", qui permettent des
transitions explicites - ISL suppose que l'intégrité des états n'est
jamais violée quelle que soit la manière d'y
parvenir, un état se manifeste et se comporte
exactement comme spécifié - Lorsqu'on sort d'un état, les attributs (visuels
et callbacks) des objets qui étaient modifiés par
cet état sont remis à leur valeur d'origine, sauf
si l'état cible exprime une condition distincte
41Exemple
- Trois objets, 1, 2 et 3
- Nous sommes dans un état A ayant les descripteurs
1 et 2 (3 non mentionné reste bleu). - On passe dans un état B décrit par 2, 3.
- ISL suppose que 1 est régénéré, donc l'état
atteint est 1, 2, 3 - Si maintenant on quitte l'état B, on retrouve 1,
2, 3
42Objets à leur création
- On crée trois objets colorés. Chaque instance
reçoit une couleur par défaut.
2
1
3
global
B
A
43Etat global (racine)
- L'interface définit un état global, qui définit
pour les différents objets une valeur
particulière de l'attribut couleur
2
1
3
global
B
A
44On passe dans l'état A
- Descripteurs 1 et 2 (3 non mentionné reste bleu)
2
1
3
global
B
A
45On passe dans l'état B
- Décrit par 2, 3. 1 est remis dans son état
d'origine
2
1
3
global
B
A
46On quitte l'état B
- Les objets reprennent leurs attributs d'origine
2
1
3
global
B
A
47Changement d'état trois cas
Etat B
Etat A
p1invisible
p1visible
b1actif
b1rouge
- Lors du passage de A vers B
- la couleur de b1 est mémorisée avant d'être
modifiée, - l'état d'activité de b1 est remis à sa valeur
anciennement mémorisée, - et la visibilité de p1 est seulement modifiée
48Etat cible seul
- Une ressource n'est contrainte que dans l'état
cible - Sa valeur avant le changement doit être
sauvegardée. - La nouvelle valeur est installée
49Etat source et état cible
- Une ressource est contrainte dans les deux états
source et cible - La valeur mémorisée est conservée
- La valeur courante est modifiée conformément à
l'état cible
50Etat source seul
- Une ressource n'est mentionnée que dans l'état
source - Sa valeur doit être restaurée à la valeur
mémorisée.
51Optimisations des implantations
- Ce mécanisme peut être optimisé de diverses
manières - élimination de scintillements par l'utilisation
du double buffering - gestion intelligente des attributs de visibilité
- réduction au minimum des interventions sur
l'interface, par des calculs ensemblistes
reposant sur des tables de hachage
52Notions nécessaires
- Comme les diagrammes d'état de UML, ISL exploite
le concept d'états composites et de leurs sous
états - Egalement, le parallélisme d'ensembles d'états
est une notion nécessaire à la spécification des
interfaces homme machine
53Visibilité
- En ISL, on ne décrit jamais un changement de
visibilité d'une fenêtre par un appel explicite
aux fonctions "show()" et "hide()" - L'attribut de visibilité est positionné par des
descripteurs associés à des états - Ainsi en changeant d'état on décrit implicitement
les modifications associées de visibilité s'il y
a lieu - Au lieu de décrire par un programme les effets
d'un changement d'état implicite, on décrit
statiquement et explicitement les états par des
invariants
54Les causes des défauts d'aspect
- Le bénéfice de cette approche apparaît clairement
quand un programmeur doit décider de ce qui doit
arriver quand un changement d'état se produit, et
qu'il y a beaucoup d'états, et beaucoup de
ressources à modifier en conséquence - est ce que cette fenêtre doit rester visible?
- La difficulté de cette simple question est la
cause majeure de coûts de développement accrus,
et de manque d'ergonomie
55Références
- ISL repose sur les state charts de David Harel
(article fondateur David Harel On Visual
Formalisms. CACM 31(5) 514-530 (1988), - http//sunsite.informatik.rwth-aachen.de/dblp/db/i
ndices/a-tree/h/HarelDavid.html), - popularisé par UML (Unified Modeling Language,
http//www.rational.com/uml) - un bon site en français http//uml.free.fr
56Extensions à UML
- la notion de descripteurs d'états (qui ne sont
pas exactement atteints par les variables
d'états) - les sous ensembles d'états concurrents nommés
- une gestion des espaces de noms permettant
d'isoler des symboles potentiellement en conflit
(comme avec les packages) - la possibilité de rendre actif un état composite
sans activer aucun de ses sous états - c'est utile pour la spécification de dialogues et
n'est pas incompatible avec le modèle de David
Harel chaque automate comporte un état
"inactif" implicite
57Spécifications des IHM à l'aide d'états
58Descripteurs
- Un descripteur est un invariant portant sur la
valeur qu'une propriété doit avoir dans un état
particulier - "propriété" doit être pris au sens large
attribut visuel (visibilité, couleur, ...),
dynamique (callback ou listener, réaction à
événement, interacteur, accélérateur clavier,
etc...), mais aussi donnée membre d'une classe,
variable globale etc... - Les descripteurs ne portent que sur des objets
nommés
59Syntaxe
- La syntaxe pour les descripteurs est simple
- object "name" "resource" "value"
- sauf ambiguïté, les guillemets, le signe égal et
le point virgule sont optionnels
60Hiérarchies d'objets
- Les interfaces font toujours apparaître des
objets dans d'autres objets (par exemple dans les
frames, ou dans les menus) - On utilise soit une notation pointée
- object "name0.name1.name2" "resource" "value"
- soit une notation imbriquée
- object "name0"
- object "name1"
- object "name2" "resource" "value"
-
-
61Alias
- Dans de nombreux cas, la lisibilité des
spécifications peut être améliorée si l'on
identifie les objets graphiques par leur nom et
leur type. - Ainsi, "JFrame", "JPanel", "XmPuxhButton" sont
des alias possibles au mot cle "object", mais
également leurs versions indépendantes des
bibliothèques "frame", "panel", "button" etc... - Egalement, les versions françaises de ces mots
sont utilisables "fenêtre", "panneau", "bouton"
etc...
62Exemples de descripteurs
- panel panel1 object button1 background blue
- panel panel1 object button1 label "a label with
spaces and a newline - in it"
- panel panel2 visible true
- panel panel3 object MenuBar.File.Open callback
OpenFile() // a menu item
63Le contexte
- L'objet le plus récemment spécifié sert de
contexte pour tous les descripteurs suivants - Exemples
- panel panel1
- visibility true // appliqué à panel1
background blue // également - object button1
- foreground red //panel1.button1 callback
quit()// également - object button2
- foreground blue //panel1.button2
64Le contexte (2)
- Les mots clé identifiant des objets de haut
niveau (panel, frame, etc...) sont non enchâssés
par défaut - En cas d'ambiguïté, on utilise des accolades
- panel panel1
- visibility true // appliqué à panel1
background blue // également - panel panel2
- foreground red //panel1. panel2
-
- panel panel3 background green
65Etats
- Un état est un conteneur pour des descripteurs et
d'autres états appelés ses sous états - Quand un état devient actif, tous ses sous
descripteurs deviennent "vrais" l'interface les
implémente - Les valeurs des attributs avant le changement
doivent être mémorisées pour en permettre la
restauration ultérieure
66Syntaxe
- La syntaxe des états est la suivante
- state "nom d'état"
- liste de descripteurs et de sous états
-
- Les accolades sont obligatoires, même si l'état
ne contient ni descripteur ni sous état (ce qui
est un cas valide)
67Exemple
- state A
-
- panel MyMainWindow
- visibility true
- object ButtonQuit
- visibility true
- callback pleaseLeaveSoftware()
68Sous états
- Un sous état est seulement une déclaration d'état
imbriquée, avec ses propres descripteurs et sous
états - Les sous états héritent des descripteurs de leurs
super états - Un descripteur peut être surchargé par un sous
état
69Syntaxe imbriquée
- state A
- ... // descripteurs de A
- state B_in_A
- ... // descripteurs de B_in_A
- state C_in_B_in_A
- ... // descripteurs de C_in_B_in_A
-
-
- state D_in_A
- ... // descripteurs de D_in_A
-
70Syntaxe extraite
- Il peut être difficile de maintenir des
spécifications faisant apparaître un trop grand
nombre d'imbrications d'états. - Egalement, il est parfois nécessaire de décrire
des fragments d'une spécification dans des
fichiers séparés, ce qui exclut la syntaxe
imbriquée - state A ...
- state B_in_A A ...
- state C_in_B_in_A B_in_A ...
- state D_in_A A ...
71Héritage
- Les descripteurs d'un état sont hérités par tous
les sous états, et peuvent être localement
surchargés - state main
- panel "main panel"
- background black
- visibility true
-
- state derived main
- panel "main panel"
- // background black (hérité)
- visibility false // surchargé
72Exercices
- Décrire en ISL les états d'un bouton
- Décrire les états d'une application à deux
fenêtres, dont l'une est une fenêtre principale,
et l'autre une fenêtre d'impression par exemple
73La concurrence
- Par défaut, les sous états sont exclusifs
- Les interfaces modernes font intervenir beaucoup
de parallélisme, allant jusqu'à la mise en ouvre
de threads pour les fonctions interfacées
(compilation, édition de liens, exécution du
programme compilé etc...) - Par exemple, l'affichage d'une aide, ou le choix
d'une langue pour les labels, sont indépendantes
des autres fonctions d'une interface, et
correspondent à des états concurrents
74Notation pour la concurrence
- Par défaut, tous les sous états d'un état sont
mutuellement exclusifs au plus un est actif à
la fois - Pour décrire le parallélisme, il est nécessaire
de permettre l'existence simultanée de plusieurs
groupes de sous états, concurrents entre les
groupes, mais exclusifs en leur sein - Ces groupes s'appellent des "sous régions" en UML
(subregions)
75Syntaxe
- state child parent subregion name ...
- Cette déclaration définit "child" comme un sous
état de "parent", figurant dans la sous région
"name" - state child parent ... est une abréviation
de - state child parent subregion default ...
76Déclaration préalable des régions
- Une spécification peut déclarer les sous régions
(et permettre ainsi certaines vérifications
automatiques si l'on dispose d'un outil) - state A
- ...
- subregion A_1
- subregion A_2
- subregion A_3
-
77Sous régions Exemple
- Chaque sous région est indépendante (concurrente)
des autres - Les états de chaque sous région sont mutuellement
exclusifs - state global
- subregion locale // definitions de language
- subregion functionality // états fonctionnels
- subregion help // aide
-
78Conflits de concurrence
- C'est une erreur que deux états concurrents
formulent des descripteurs incompatibles - state root ...
- state A root functionality
- panel panel1 visibility true
-
- state B root help
- panel helpPanel visibility true // ok
- panel panel1 visibility false // erreur
-
- Deux descripteurs sont incompatibles seulement
s'ils sélectionnent des valeurs différentes pour
le même attribut du même objet
79Commentaires
- Comme les états A et B peuvent être actifs
simultanément, la spécification est inconséquente
(une implantation ferait varier l'état de
l'interface selon l'ordre de prise en compte des
états) - Le parallélisme n'a de sens que pour des
descripteurs portant sur des données séparées - Toutefois, données séparées ne signifie pas
objets distincts. Il peut exister du parallélisme
intra objet. - Par exemple, deux états concurrents peuvent agir
l'un sur la couleur de fond, et l'autre sur le
texte du label
80Etat Initial
- Chaque sous groupe d'un état possède un état
initial. - En UML cet état initial est décrit
- par une pastille noire
- Par défaut, l'état initial ne possède ni
descripteurs, ni sous états (il est "vide"), et
il s'appelle "initial" - Lorsque une interface est placée dans un état
donné, tous les états initiaux de tous ses sous
groupes sont activés récursivement.
81Syntaxe
- On peut spécifier un état particulier comme état
initial d'un sous groupe donné - state A
- subregion A_1 initial B
- ...
-
- Il y a au plus un état initial par sous groupe.
Si la spécification définit un état initial, elle
doit recourir à la déclaration préalable du sous
groupe correspondant
82Rôle des états initiaux
- Cette fonctionnalité est utile comme une
abstraction. Un état appelé "impression" peut
être utilisé par l'ensemble d'une équipe, ou
identifié tôt dans le processus de spécification,
sans préjuger de son implantation finale. - On peut aussi admettre, à l'instar des fichiers
de défaults de XWindow, qu'un utilisateur avancé
puisse changer des états initiaux d'une interface
qu'il utilise souvent
83Exemple
- state abstract_global
- subregion "default" initial concreteB1
- subregion "help" initial abstractB2
- // default subregion
- state concreteA1 ...
- state concreteB1 ...
- // help subregion
- state concreteA2 help ...
- state abstractB2 help
- subregion "default" initial concrete_deep_B
- state concrete_deep_A...
- state concrete_deep_B...
-
-
- En activant abstract_global, on active en fait
concreteB1 et parallèlement concrete_deep_B
84Commentaires
- Le concepteur d'un état peut contrôler
l'établissement automatique d'un sous état - Les autres parties de la spécification peuvent
connaître l'abstraction en ignorant les détails
de la spécification - Le concepteur de l'abstraction a une totale
liberté pour définir la structure réelle de
l'abstraction
85Espaces de noms
- Les états initiaux permettent de facilement
séparer le travail de spécification entre
plusieurs ingénieurs. - Le besoin d'éviter des conflits de noms apparaît
spontanément dans ce cadre. - ISL permet une gestion explicite des espaces de
noms au moyen d'états "packages" - state package rootstate
- ...
86Règles de nommage
- L'état racine d'une spécification est par défaut
un package - Les noms d'états sont uniques dans leur package
- Désigner un état ambigu se fait en utilisant son
nom de package en préfixe (packagestate). - Dans le cas où les noms de packages ne sont pas
uniques dans la spécification, on utilise la
suite complète des packages qui le contiennent
(package1... packagenstate)
87Désigner les états
- Quand un état est désigné dans un descripteur par
un nom simple, dans le contexte d'un package
donné, l'état portant ce nom est cherché dans ce
package exclusivement - Dans tous les autres cas, il convient d'employer
une notation non ambiguë mentionnant les noms de
packages de façon explicite
88Les callbacks setState et leaveState
- ISL prévoit deux callbacks prédéfinis pour les
changements d'états - Les fonctions correspondantes sont utilisées
comme "valeurs" de descripteurs de callbacks - exemple
- ... object buttonOK
- callback setState(astate)
- ... object buttonCancel
- callback leaveState(current)
89Définitions
- setState positionne l'état courant
- ce n'est pas une erreur si cet état est déjà
actif - si c'est le cas, les sous états actifs sont
abandonnés, et l'oin procède comme pour le
premier établissement de l'état (i.e.
relativement aux états initiaux) - leaveState abandonne son état argument, à
condition qu'il soit actif - leaveState abandonne également tous les sous
états - leaveState réactive l'état initial du groupe
auquel l'état abandonné appartient
90Set Vs Leave
- Quand B est un sous état de A, quitter B n'est
pas équivalent à positionner A. - Quand on fait "set" (A), on réactive tous les
sous états initiaux de A - Quand on fait "leave" (B), on ne réactive que le
seul état initial du sous groupe de A auquel
appartient B - LeaveState est donc une facilité pour désactiver
sélectivement un sous groupe donné
91Exemple
- state A
- panel panel1 object button1
- callback setState(B)
- ...
- state B
- panel panel1 object buttonOk
- callback setState(A)
- panel panel1 object buttonCancel
- callback leaveState(B)
- ...
-
-
92Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
93Etats composites un support pour l'abstraction
- Il est souvent utile de considérer des états
comme des abstractions pour d'autres - Par exemple, le mode MoveResize d'une interface
- On peut définir un état "MoveResize", abstraction
pour plusieurs sous états comme
"NothingSelected", "ButtonDownInsideObject", "
ButtonDownInsideResizingBox ". - Certaines caractéristiques de l'interface son
communes à ces trois états (icône, transitions
vers d'autres états etc...)
94Factoriser les descripteurs
- L'ensemble des descripteurs communs à des états
voisins peuvent être adéquatement groupés dans un
super état abstrait - L'utilisation d'états initiaux permet de garantir
qu'un tel état abstrait ne soit jamais actif
isolément
95Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
- Exemples
- Définir une interface avec des états
96Objectif exemple 1
- On imagine l'interface d'un éditeur simplifié.
- Il a pour fonctions l'édition bien sûr, et aussi
la sauvegarde, l'ouverture de fichier,
l'impression et la recherche dans le texte
appelées - lteditgt, ltloadgt, ltsavegt, ltfindgt et ltprintgt.
97Analyse du module fonctionnel
- lteditgt est une fonction interne de l'interface,
ainsi que ltfindgt. Les fonctions ltsavegt, ltloadgt,
et ltprintgt sont des appels au système, qui est
perçu comme le module fonctionnel interfacé - Il n'y a pas de protocole particulier pour
ltsavegt, ltloadgt, et ltprintgt. - Ces trois opérations peuvent être effectuées dans
n'importe quel ordre - (on ignore le fait que la sauvegarde puisse dans
un programme intelligent rester impossible tant
que rien n'a été édité)
98Identifier les fenêtres principales
- L'application a un panneau principal appelé
"mainPanel". - On y trouve la barre de menu et la zone de
travail - ltsavegt et ltloadgt partagent une fenêtre de
sélection de fichier appelée "fileSelector". - ltprintgt prend ses paramètres grâce à un panneau
"printParameters" - ltfindgt requiert un panneau "findPanel".
99Concevoir l'automate
- lteditgt est concurrente avec le reste des
fonctions - ltfindgt n'a pas d'impact sur les données, et est
également indépendante des autres fonctions - on décide également que ltsavegt et ltprintgt sont
concurrentes entre elles - leurs fenêtres caractéristiques peuvent être
simultanément visibles - ltloadgt est exclusive de ltsavegt et ltprintgt.
- quand l'utilisateur initié un dialogue ltloadgt,
les dialogues ltprintgt et ltsavegt disparaissent
s'ils étaient visibles. - ltloadgt et ltsavegt étant exclusifs, ces états
peuvent partager la même fenêtre de sélection de
fichiers.
100Développer la structure générale des états
- state package editor
- // the default subregion is kept for standard
editor functionalities - panel mainPanel visible true
- object menuBar.File.Open callback
setState(load) - object menuBar.File.Save callback
setState(save) - object menuBar.File.Print callback
- setState(print)
- object menuBar.Edit.Find callback
setState(find) - panel fileSelector visible false panel
printParameters visible false - panel findPanel visible false
101ltFindgt, ltLoadgt
- state package editor ...
- subregion find_subregion ///////////////////////
/////////// - state find find_subregion
- panel findPanel visible true
- object close callback leaveState(find)
object search callback doSearch() -
- subregion lps_subregion ////////////////////////
////////// - state load editor lps_subregion
- panel fileSelector visible true
- object close callback leaveState(load)
object ok callback loadFromFile() -
102saveOrPrint (abstraction)
- state saveOrPrinteditor lps_subregion //
default subregion not used, abstract state - state save save_subregion panel
fileSelector visible true object close
callback leaveState(save) object ok callback
saveToFile() - state print print_subregion panel
printParameters visible true object close
callback leaveState(print) object ok callback
print() -
103Commentaires
- L'exemple à ce stade illustre de quelle manière
des états abstraits peuvent être utilisés pour
grouper des informations communes à plusieurs
sous états - En particulier, cela sert à définir une fois pour
toutes de valeurs pas défaut, chaque sous état
étant défini par différence avec ses super états - Il est d'usage que l'état racine soit qualifié de
"package" pour signifier qu'il constitue un
espace de noms
104Objectif exemple 2
- Vous êtes le concepteur interface pour la
commande d'une locomotive à vapeur - La spécification doit décrire la dynamique de
cette interface. - Certains états sont concrets, et ont pour
vocation d'être activés - D'autres sont abstraits et groupent des
descripteurs partagés sans avoir pour vocation à
être activés isolément
105Hypothèses
- La machine peut être garée (à l'arrêt moteur
froid) - à l'arrêt,
- chaudière en chauffe,
- chaudière chaude,
- en mouvement
- chaudière en cours de refroidissement
- chaudière froide
106Global
- state global // abstract
- // spécifie la barre de menus
- // les callbacks de menus sont positionnés
- // mais insensitifs
- initial Parked
- panel mainControlPanel visibility true
- object MenuBar.Engine.Operate
- callback setState(InOperation)
- sensitivity false
- object MenuBar.Engine.Park
- callback setState(Parked)
- sensitivity false
- panel mainEnginePanel visibility false
107Parked
- C'est l'état initial
- state Parked global
- panel mainControlPanel
- object MenuBar.Engine.Operate sensitivity
true
108InOperation
- state InOperation global // abstract
- initial BoilerHeatingAndStopped
- panel mainEnginePanel
- visibility true
- object StartButton visibility false
- object StopButton visibility false
- object TemperatureHotEnough
- visibility false
- object TemperatureColdEnough
- visibility false
- object CoolBoiler visibility false
- object Quit visibility false
109BoilerHeatingAndStopped
- state BoilerHeatingAndStoppedInOperation
- // le premier état atteint lors de
- // la mise en opération
- panel mainEnginePanel
- object TemperatureHotEnough
- visibility true
- callback setState(BoilerHot)
-
110BoilerHot
- state BoilerHotInOperation // abstract
- initial Stopped
- state Stopped
- // on peut démarrer
- // ou refroidir
- panel mainEnginePanel
- object CoolBoiler
- visibility true
- callback setState(BoilerCooling)
- object StartButton
- visibility true
- callback setState(Running)
-
111Running
- state RunningBoilerHot
- // la seule transition possible
- // est vers "stopped"
- panel mainEnginePanel
- object StartButton
- visibility false
-
- object StopButton
- visibility true
- callback setState(Stopped)
-
-
112BoilerCooling
- state BoilerCoolinginOperation
- // on attend que la température soit assez
- // basse pour garer la locomotive
- // la décision est sous contrôle de
- // l'utilisateur (click "ok, cold enough")
- panel mainEnginePanel
- object TemperatureColdEnough
- visibility true
- callback setState(BoilerCold)
-
113BoilerColdInOperation
- state BoilerColdInOperation
- // la machine peut être garée
- panel mainControlPanel
- object MenuBar.Engine.Park sensitivity
true - panel mainEnginePanel
- visibility true
- object Quit callback
- setState(Parked)
-
114Combiner macro et micro automates
- ISL est utile pour décrire des états de haut
niveua dans une IHM, comme ceux liés aux
visibilités de fenêtres, aux callbacks,etc... - Les fonctionnalités d'une machine d'états finis
peuvent être également utilisées pour décrire
des automates plus élémentaires sélection,
dimensionnement, déplacement d'objets 2D... - Tous les aspects de la dynamique interne d'une
IHM peuvent être traduits en terme d'automates
d'états finis (généralement, on utilise des
composants prédéfinis qui gèrent déjà en interne
ces automates)
115Efficacité
- Une implantation de ISL peut être efficace
- quand on quitte un état A pour un état B, on
reste dans un état commun le plus spécifique C - l'algorithme pour gérer le changement d'état peut
être linéaire sur le nombre de spécifications
d'état applicables à B et A qui ne sont pas
héritées de C
116Applications
- Des changements subtils dans l'interface peuvent
être modélisés au moyen d'états sans perdre
d'efficacité - L'algorithme ne changera pas les performances
générales du programme, car il ne fait que ce qui
est strictement nécessaire, sans surcoût
117Améliorations de performances
- Il est même possible qu'une implantation de ISL
conduise à des programmes plus efficaces - Cela est dû au fait que le programme de
changement d'état ne teste jamais l'état courant
pour déterminer le traitement à réaliser - Les callbacks peuvent être installés
dynamiquement, et changer pour le même objet dans
des états distincts
118Callbacks
- ISL gère les callbacks en installant et
désinstallant les pointeurs vers les fonctions
dynamiquement. - Contrairement à un programme standard, les
callbacks ne commencent jamais par des batteries
de tests
119Classes vs Etats
- La différence entre classes et états est minime
- L'état d'un objet peut changer, mais pas sa
classe - Cette nuance est due à des raisons techniques,
l'implantation des objets reposant sur des
concepts comparables aux "struct" C
120Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
121Que doit on faire?
- utiliser des schémas d'interaction bien connus,
et singer les interfaces que l'on préfère - définir des standards de spécification/conception
d'interfaces que les programmeurs doivent
respecter - par exemple le dialogue de confirmation
- Lier précisément les artéfacts visuels et la
sémantique - le même "signe" (la couleur "rouge" d'un bouton
par exemple) doit avoir une signification
constante dans l'interface - préférer le Undo à la confirmation
- utiliser les états
122Que doit on éviter?
- de court circuiter les états avec des callbacks
ayant des effets de bord - d' utiliser plus qu'un nombre limité (trois) de
signes visuels percutants dans une fenêtre - d'utiliser trop de couleurs
- de faire bouger les objets
- de faire une interface dont la moyenne des
couleurs soit trop éloignée du gris
123Que peut on raisonnablement faire?
- réutiliser la même fenêtre dans plusieurs états
exclusifs - par exemple la fenêtre de sélection de fichiers
124Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
125Processus de spécification
- ISL ne modifie pas les phases amont de la
spécification d'une interface - Il permet de décrire le comportement des panneuax
de l'interface sans programmer - La spécification des panneaux demeure une tâche
fondamentale - Nous proposons un processus simplifié de mise en
uvre de la méthode
126Décrire le protocole applicatif
- Le module fonctionnel interfacé obéit à un
protocole les appels de fonctions ne sont pas
libres et indépendants (comme pour une pile) - L'interface aura pour rôle de donner accès à
ce(s) module(s) fonctionnel(s) en guidant
l'utilisateur ou en évitant ses erreurs - La première chose à faire est de décrire
l'automate des modules fonctionnels (exemple
winamp)
127Style de programmation
- Un module fonctionnel ne corrige généralement pas
les erreurs (programmation dite de type
"défensif") mieux que par le lancement
d'exceptions (qui normalement arrêtent
l'exécution) - Le style de programmation est dit "généreux"
(generous) une erreur d'interaction (mauvais
moment d'appel, mauvais paramètre) provoque un
arrêt brutal. - Il est déraisonnable de dupliquer la logique de
filtrage/correction d'erreurs dans l'interface et
dans le module fonctionnel.
128Machine d'états du module fonctionnel
- On décrit un protocole avec des diagrammes
d'états UML - évènements lt-gt appels de fonction
- Cet automate sert de guide pour la spécification
de l'automate de l'interface - arguments de fonctions données saisies dans
l'interface
129Sémantique de l'interface
- Certaines des fonctions d'un module fonctionnel
sont essentielles, d'autres plus auxiliaires - les fonctions essentielles sont celles aui
correspondent à la raison d'être du programme - ex login sur db / requête sur db
- Identifier ces fonctions c'est isoler la
"sémantique" de l'interface
130Définir les panneaux principaux
- C'est la première étape
- Leur contenu dépend du protocole fonctionnel, et
des données à fournir en paramètre - Les choix faits pour les gadgets reposent sur la
charte graphique
131Définir l'automate global
- Après la spécification des panneaux vient la
spécification des états principaux de
l'interface. - Les états sont identifiés, hiérarchisés, et la
question de leur concurrence est posée
132Définir les packages
- Eventuellement, des états peuvent être
sélectionnés pour isoler un espace de noms de
l'extérieur - Cette fonctionnalité est essentielle pour
développer des automates sans risques de conflit
de nommage - ex "confirmer" / "quitter"
133Schémas d'états
- On peut aussi réutiliser un schéma d'états
préexistant (par exemple pour l'interaction de
type confirmation/annulation - L'automate développé doit respecter le standard
syntaxique. Un moyen de le garantir est
précisément de réutiliser des schémas
d'interaction. - Le moyen le plus habituel de le faire est de
réutiliser des objets de niveau dialogue (par
exemple la boite de sélection de fichiers)
134Compléter l'automate
- définir la hiérarchie
- définir les callbacks de transition
- décider des options de visibilité de panneaux
135Raffiner l'automate
- panneaux auxiliaires (messages...)
- états auxiliaires, transitions associées,
confirmations, etc - on continue à respecter la charte syntaxique
136Décorer l'interface
- On améliore l'ergonomie
- artéfacts visuels
- compléments d'information (messages, tooltips
etc) - l'interface peut informer l'utilisateur sur
- l'état courant
- l'objectif visé (imprimer, faxer, enregistrer,
éditer, etc... - les alternatives possibles
- Ces ajouts doivent suivre une charte sémantique,
afin de garantir l'aspect homogène de l'interface
137Augmenter le nombre de transitions
- On ajoute des transitions qui fournissent des
raccourcis, afin d'améliorer la navigation - boutons bascule
- fenêtres qui provoquent lors d'un click où
passage au premier plan (mapping) le changement
d'état vers ce à quoi elles servent - On peut viser à couvrir le plus possible du
graphe d'états de façon à le rendre quasi complet
138Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
139Niveau lexical
- Style des polices de caractères
- apparence des boutons ok, quit, cancel etc...
- apparence des labels
- dimensions et positions des différentes
catégories de panneaux
140Niveau syntaxique
- Chaque objectif peut être atteint par différentes
séquences d'interaction - Chaque séquence fait intervenir des éléments du
niveau lexical - La réunion de ces séquences est le protocole de
l'interface - Pour garantir l'utilisabilité de l'interface, les
séquences doivent être les mêmes pour des
opérations similaires
141Exemple
- La séquence confirmation / annulation
- fenêtre de confirmation ?
- click supplémentaire sur le bouton après avoir
changé le label? - sélection multi niveau
- cascade de popup menus ?
- affichage répété de listes intermédiaires?
- utilisation d'objet "tree"
142Schémas Interaction Patterns
- Un produit utile de la charte syntaxique est la
définition de schémas d'automates pouvant êtyre
réutilisés - C'est une manière simple d'améliorer les chances
de respects de cette charte
143Le niveau sémantique
- L'utilisateur poursuit toujours un ou plusieurs
objectifs simultanés - l'interface doit donner des signes visibles à
tout moment de ce qui est en cours - Ces signes doivent être homogènes dans toutes les
situations
144Le niveau sémantique
- On doit pour cela lister les fonctions
essentielles, et leur associer des artéfacts
visuels, si possible compatibles avec la
concurrence, si les fonctions peuvent être
accédées simultanément - L'interface devrait en permanence répondre
visuellement à la question "pourquoi suis-je là" - C'est également un point requis par les exigences
de sécurité dans le cas des grandes interfaces
145Séquences obligatoires / états
- On appelle séquence obligatoire une séquence
d'interaction minimale pour atteindre uin
objectif - par exemple pour imprimer
- Chaque étape correspond à au moins un état de
l'interface - On peut se demander si ces états sont imbriqués
ou frères (ils sont bien sûr exclusifs)
146Préférer l'héritage
- les états d'une séquence diffèrent généralement
peu de l'un à l'autre, si ce n'est pas quelques
visibilités de panneaux - cela peut être une bonne idée de laisser les
fenêtres intermédiaires visibles, afin de
permettre un retour en arrière direct
147Autres arguments
- L'utilisateur / le programmeur ont souvent
l'impression de s'enfoncer dans un processus en
suivant une séquence - les états imbriqués en fournissent une bonne
métaphore - les choix réalisés à chaque étape correspondent à
des sous états exclusifs
148Modalité
- La modalité est positive quand l'utilisateur
gagne des possibilités suite à un changement
d'état - Elle est négative dans le cas inverse
- Les fenêtres modales (bloquantes) doivent être
évitées à tout prix car anti-ergonomiques - Ces fenêtres implantent la forme la plus forte de
modalité négative, qui interdit généralement des
actions possibles sans danger
149Cas possibles de fenêtres modales
- Dans les systèmes critiques (monitoring de
centrale nucléaire par ex) si l'application doit
recevoir une réponse à tout prix - Dans une file de séquence quand les paramètres de
la phase précédent ne peuvent plus être changés
150Modalité négative et états
- state print
- panel parameters visible true
- object print callback setState(confirm)
- panel confirmation visible false
-
- state confirm print
- panel confirmation
- visible true // positive modality
- object close callback setState(print)
- object apply callback doPrint()
- panel parameters
- visible false // negative modality
151Langage de Spécification d'Interfaces(Spécificati
ons des IHM à l'aide d'états)
- Exemple
- Raffiner une interface avec des états
152Objectif
- On reprend l'interface de l'éditeur simplifié vu
précédemment - Il a pour fonctions l'édition bien sûr, et aussi
la sauvegarde, l'ouverture de fichier,
l'impression et la recherche dans le texte
appelées - lteditgt, ltloadgt, ltsavegt, ltfindgt et ltprintgt.
- On illustre le processus décrit précédemment
153Analyse du module fonctionnel
- lteditgt est une fonction interne de l'interface,
ainsi que ltfindgt. Les fonctions ltsavegt, ltloadgt,
et ltprintgt sont des appels systèmes, perçu comme
le module fonctionnel - Il n'y a pas de protocole pour ltsavegt, ltloadgt, et
ltprintgt. - Ces trois opérations peuvent être effectuées dans
n'importe quel ordre - (on ignore le fait que la sauvegarde puisse dans
un programme intelligent rester impossible tant
que rien n'a été édité)
154Identifier les fenêtres principales
- L'application a un panneau principal appelé
"mainPanel". - On y trouve la barre de menu et la zone de
travail - ltsavegt et ltloadgt partagent une fenêtre de
sélection de fichier appelée "fileSelector". - ltprintgt prend ses paramètres grâce à un panneau
"printParameters" - ltfindgt requiert un panneau "findPanel".
155Concevoir l'automate
- lteditgt est concurrente avec le reste des fonction
- ltfindgt n'a pas d'impact sur les données, et est
également indépendante des autres fonctions - on choisit aussi que ltsavegt et ltprintgt sont
concurrentes entre elles - leurs fenêtres caractéristiques peuvent être
simultanément visibles - ltloadgt est exclusive de ltsavegt et ltprintgt.
- quand l'utilisateur initié un dialogue ltloadgt,
les dialogues ltprintgt et ltsavegt disparaissent
s'ils étaient visibles. - ltloadgt et ltsavegt étant exclusifs, ces états
peuvent partager la même fenêtre de sélection de
fichiers.
156Développer la structure générale des états
- state package editor
- // the default subregion is kept for standard
editor functionalities - panel mainPanel visible true
- object menuBar.File.Open callback
setState(load) - object menuBar.File.Save callback
setState(save) - object menuBar.File.Print callback
- setState(print)
- object menuBar.Edit.Find callback
setState(find) - panel fileSelector visible false panel
printParameters visible false - panel findPanel visible false
157ltFindgt, ltLoadgt
- state package editor ...
- subregion find_subregion ///////////////////////
/////////// - state find find_subregion
- panel findPanel visible true
- object close callback leaveState(find)
object search callback doSearch(find) -
- subregion lps_subregion ////////////////////////
////////// - state load editor lps_subregion
- panel fileSelector visible true
- object close callback leaveState(load)
object ok callback loadFromFile() -
158saveOrPrint (abstraction)
- state saveOrPrinteditor lps_subregion //
default subregion not used, abstract state - state save save_subregion panel
fileSelector visible true object close
callback leaveState(save) object ok callback
saveToFile() - state print print_subregion panel
printParameters visible true object close
callback leaveState(print) object ok callback
print() -
159Commentaires
- L'exemple à ce stade illustre de quelle manière
des états abstraits peuvent être utilisés pour
grouper des informations communes à plusieurs
sous états - En particulier, cela sert à définir une fois pour
toutes de valeurs pas défaut, chaque sous état
étant défini par différence avec ses super états - Il est d'usage que l'état racine soit qualifié de
"package" pour signifier qu'il constitue un
espace de noms
160Raffiner la structure de l'automate
- On ajoute une fenêtre de confirmation pour
l'impression - Cela requiert l'ajout d'une fenêtre, et d'un état
qui contrôle sa visibilité. - C'est illustré comme suit
161Dialogue de confirmation
- state print saveOrPrint print_subregion
- panel printConfirm visible false
- panel printParameters visible true
- button close callback leaveState(print)
- button ok callback setState(printConfirm)
- state printConfirm
- panel printConfirm visible true
- object ok callback print()
- object cancel callback leaveState(print)
-
-
162Augmenter le nombre de Transitions
- L'exemple précédent introduit une fenêtre de
confirmation mais ne masque pas la fenêtre de
paramètres . - Cela offre plusieurs avantages
- 1- la fenêtre de paramètres reste ouverte de
sorte que l'on sache ce que l'on est en train de
confirmer - 2 - cela facilite le retour à cette fenêtre de
paramètres - 3 - cela permet de donner au bouton "print" une
fonction de bascule, particulièrement ergonomique
163Raffiner
- On adapte l'automate en modifiant le sous état
"printConfirm" de "print". - Le bouton print, au lieu de lancer l'impression,
passe dans l'état "printConfirm". - Dans l'état printConfirm, ce même bouton a pour
fonction de quitter l'état printConfirm (et donc
dans cet exemple simple de revenir à l'état print)
164Ajout de Transitions
- state print saveOrPrint print_subregion
- panel printConfirm visible false panel
printParameters visible true - object close cb leaveState(print)
- object ok cb setState(printConfirm)
- state printConfirm
- panel printConfirm visible true
- object ok cb print()
- object cancel cb leaveState(print)
- panel printParameters
- object close cb leaveState(printConfirm)
- object ok cb leaveState(printConfirm)
-
165Conclusion
- ISL est un langage puissant pour la spécification
d'interfaces - ISL étend les diagrammes d'états de UML
- ISL peut être rendu exécutable
166Annexe, compléments de notation
167Messages
168Evenements déférrés
169Extension (2)
170Exemple
171Exemple