UNIVERSITE DE LA MANOUBA
-----¤¤¤¤-----
ECOLE NATIONALE DES SCIENCES DE
L'INFORMATIQUE
Série N°3: Modélisation structurelle UML
Matière : ACOO
A.U. : 2015-2016
Niveau : I.I. 2
Correction de l’exercice 1
L’objectif de ce problème est de développer une application permettant de faire calculer à des
robots des itinéraires dans différentes zones géographiques. Un robot calcule un itinéraire lors de
son déplacement dans une zone géographique. Chaque zone géographique dispose d’un certain
nombre d’obstacles dont le nombre et la position
de chaque obstacle sont connus à l’avance et fixes.
Dans le cadre de ce problème, une zone géographique est une grille de forme rectangulaire dont la
taille est de NxM cases. Au départ, le robot est situé sur une case désignée par case de départ. Le robot
calcule un itinéraire formé d’une succession de cases qu’il peut visiter pour se rendre à une case de la
grille désignée par case d’arrivée. Il convient de mentionner qu’une case peut être visitée plus qu’une
fois. Un itinéraire peut être construit que lorsqu’on connaît les cases de départ et d’arrivée qui restent
inchangées. On suppose que les robots se déplacent dans l’une des quatre cases voisines à la sienne
(haut, bas, gauche, droite) à condition qu’elle ne soit pas un obstacle (cercle noirci).
La figure à droite représente une zone géographique composée de sept obstacles avec un robot (nommé
Zulu) initialement dans une case de départ devant se rendre à une case cible (quadrillée).
Dans un premier temps, on se propose d’utiliser
uniquement les 4 classes : Grille, Robot, Case et Itineraire. Un développeur a réalisé le modèle de
conception UML incomplet suivant :
Travail à faire
On se propose de comprendre, compléter et d’améliorer la modélisation UML proposée par le
développeur.
1. a) Vous remarquez l'utilisation d'un type particulier d'association dans le diagramme de
classes proposé par le développeur. Lequel ? Rappelez sa définition.
1
association unidirectionnelle = navigation dans un seul sens
b) Commentez la signification de chaque association dans le diagramme proposé par le
développeur.
Grille-Robot (habitant) : une grille peut contenir 0 ou plusieurs habitant de type robot
Grille-Case (Obstacle) : une grille contient 0 ou plusieurs obstacles de type case
Itineraire-Case (départ) : un itinéraire à 1 et une seule case de départ
Itineraire-Case (arrivée) : un itinéraire à 1 et une seule case d’arrivée
Itineraire-Case (chemin) : un itinéraire est formé par à 0 ou plusieurs cases visitées formant ainsi un chemin
2. Elaborez le diagramme d’objets représentant la zone géographique présentée dans la
première figure (avec 1 zone géographique, 7 obstacles, un robot). Prenez les
conventions suivantes : la position 0,0 correspond au coin haut gauche de la grille, les
colonnes positives à droite, les lignes positives en bas.
3. De petites modifications s’avèrent nécessaires pour que la classe Robot puisse réaliser le
traitement de la méthode « atteindrePosition » assurant le calcul d’un itinéraire. Voici un
exemple de modification qu’il est possible d’apporter à la classe Robot :
i.
ii.
Ajouter un attribut nommé zoneDuRobot dont le type est un pointeur sur la Grille
Ajouter l’opération presenceObstacle qui retourne vrai en cas d’existence d’obstacle
à la position (x,y)
a) Reflétez cette modification sur le modèle UML en représentant que les classes
concernées par le changement.
b) Une instance de la classe Itineraire peut-elle reconnaître les obstacles ? Justifier votre
réponse.
Non, car à partir d’une instance itinéraire on ne peut naviguer que vers : case départ, case
d’arrivée et les cases visitées par le robot.
Advertisement
Rq : A partir de case on n’a pas de visibilité sur les obstacles. La seule classe qui a une visibilité
sur les obstacles est la classe Grille ou toutes celles qui peuvent naviguer vers grille (soit Robot).
2
4. Pour la compréhension de l’évolution du modèle objet, on se propose de décorer les
associations par les contraintes de gestion : frozen, addOnly, ordered, notUnique.
a) Rappelez la signification de chacune de ces contraintes.
frozen : le tissage des liens est fixé lors de la création et ne peut pas changer.
addOnly : Il est possible de tisser de nouveaux liens mais impossible d’en supprimer
ordered : les éléments de la collection représentant le tissage des liens sont ordonnés
notUnique : Il est possible d’avoir plus qu’un lien entre deux objets avec la même association
b) Décorez chaque association par le ou les contraintes de gestion appropriées. Il est
conseillé de donner une réponse textuelle : le ou les contraintes par association (une
ligne par association).
Grille-Robot (habitant) :
Grille-Case (Obstacle) : frozen,
Itineraire-Case (départ) : frozen
Itineraire-Case (arrivée) : frozen
Itineraire-Case (chemin) : notUnique, addOnly, ordered
c) Discutez brièvement l’impact des contraintes de gestion des associations dégagées dans
la question précédente sur les méthodes des classes.
Frozen : l’initialisation doit se faire au niveau du constructeur
notUnique : prévoir un moyen pour distinguer 2 liens sur un même objet (par exemple en
duplicant les objets !)
addOnly : prévoir au niveau des méthodes l’ajout et/ou l’insertion (add) pas de suppression
ordered : prévoir un ordre (soit par chainage entre les éléments ou par un index sur l’élément
pas de contraintes : il faut prévoir toutes les méthodes (add, insert , remove, removeAll, etc.)
d) L’implémentation des associations avec cardinalité multiple nécessite l’utilisation d’une
structure qui implémente une collection (non définie dans le modèle UML proposé par le
développeur). Quelle structure vous comptez utiliser pour les différentes associations
multiples. Justifiez votre choix.
Grille-Robot (habitant) : Aucune contrainte n’est indiquée dans l’énoncé. Donc on a besoin
d’une collection dont la taille n’est pas connue à priori => liste simplement ou doublement
chaînée. Aucune contrainte sur l’ordre entre les habitants => on peut choisir liste simplement
chaînée
Grille-Case (Obstacle) : on a besoin d’une collection dont la taille n’est pas une constante
indépendante de la grille et donc on écarte l’utilisation d’un tableau statique. Mais la taille de la
collection est une valeur connue lors de la construction de la grille => on peut opter pour un
tableau dynamique. Mais comme la grille ne connaît pas le nombre d’obstacles => plus propice
d’utiliser une liste simplement chaînée.
Itineraire-Case (chemin) : on a besoin d’une collection dont la taille n’est pas connue à priori.
L’ordre sert uniquement pour former une succession de cases. On n’a pas besoins d’opération
qui exploite le double chainage => liste simplement chainée
5. On rappelle que dans la question 3, on a rajouté l’opération presenceObstacle dans la classe
Robot. Est-il possible de déplacer cette opération dans une autre classe ? Justifiez votre
réponse.
3
Oui il est possible de déplacer l’opération « presenceObstacle » dans une autre classe car la
classe responsable est la classe Grille. C’est elle qui contient toutes les informations pour
pouvoir réaliser le traitement.
6. On veut savoir s’il est possible de mémoriser les itinéraires suivis par chaque Robot. Est-il
possible de le faire avec l’association «habitant» entre les classes Grille et Robot et/ou une
autre association de la solution actuelle ? Justifiez votre réponse ?
Avec la solution actuelle, par l’association « habitant » entre les classes Grille/Robot il n’est pas
possible de mémoriser les itinéraires suivis par chaque robot.
Il s’agit de démontrer que toutes les navigations ne permettent pas de joindre le robot avec l’itinéraire.
D’ailleurs, ce dernier est transmis par un return dans une méthode de Robot.
Toutefois, on peut le faire avec plusieurs façons. Voici à titre d’exemple 1 façon :
Ajouter une association entre Robot et Itinéraire [1-*] (Robot se déplace plusieurs fois pour calculer
Advertisement
itinéraire). Plus il faut que l’itinéraire soit relatif à une grille rendre Grille une classe
associative de la nouvelle association.
7. On se propose d’ajouter la classe Application qui joue le rôle d’interface entre le programme
principal et les constituants du problème en question (Grille, Robot, Case, Itineraire). A cet
effet, on se propose aussi de transformer toutes les associations dans le diagramme de
classes réalisé par le développeur en introduisant, si c’est possible, un maximum
d’association de type composition ou à la limite des associations de type agrégation.
Rappelez la définition de ces deux concepts et donnez une proposition d’un nouveau
diagramme de classes incluant la classe Application.
L’agréation est un cas particulier d’association qui représente une relation d’inclusion structurelle ou
comportementale d’un élément (agrégé) dans un ensemble (agrégat). La durée d vie des agrégés est
indépendante de celle de l’agrégat. Il est possible de rattacher les agrégés à plus d’un agrégat. La
composition est un cas particulier d’association avec des contraintes décrivant la notion de composant
(contenance structurelle). Les contraintes liées à la composition sont les suivantes :
- Un objet composant ne peut être que dans un seul objet composite.
- Un objet composant n’existe pas sans son objet composite.
- Si un objet composite est détruit, ses composants aussi.
4
Correction de l’exercice 2
L’objectif de cet exercice est l’analyse et la conception, en partie, d’une version simplifiée d'un jeu
mettant en opposition un Pacman et plusieurs adversaires. Ce jeu permet à un joueur de déplacer
son Pacman dans un labyrinthe contenant des tonneaux. Lors de son passage, le Pacman peut boire
des potions d’énergie qui sont dans des tonneaux. La partie est gagnée quand le Pacman atteint une
case ‘jocker’. La partie est perdue quand le Pacman est tué par un adversaire.
Dans le cadre de ce problème, on suppose que le labyrinthe est composé d’un ensemble de cases (n
lignes, m colonnes) et, par conséquent, il est de forme rectangulaire. Les cases du labyrinthe
peuvent être de l’une de ces 3 catégories : ‘Simple’, ‘Prison’ ou ‘Jocker’. Chaque case de ce
labyrinthe peut contenir au plus un tonneau, mais peut abriter un nombre quelconque d’occupants :
le Pacman et/ou des adversaires. On suppose que chaque tonneau contient une quantité infinie de
potions d’énergie et ne change pas de place au cours du jeu. Si deux occupants de natures
différentes se trouvent sur la même case, ils s’attaquent et en fonction de leurs états respectifs, l’un
d’eux tue l’autre. On suppose aussi que le déplacement d’un occupant se fait sur l’une des quatre
cases voisines à la sienne. Dans le cas où le déplacement fait ressortir l’occupant du labyrinthe, ce
dernier réapparait sur le côté opposé du labyrinthe.
Le Pacman est initialement immobile. Le déplacement du Pacman est commandité par le joueur. Ce
dernier lui donne une direction (haut, bas, gauche, droite). Le Pacman se déplace à des fréquences
périodiques dans le couloir où il se trouve et dans la direction donnée par le joueur. Le Pacman ne
peut pas visiter la case "prison" et dans le cas où il la rencontre dans son chemin il s'arrête. Il est à
noter qu'un couloir est une succession de cases sur une même ligne (respectivement même colonne)
du labyrinthe.
Le Pacman est initialement dans un état ‘non agressif’. Dans cet état, il peut être attaqué par un
Adversaire. Mais, le Pacman peut à son tour attaquer quand il est à l’état ‘agressif’. Le Pacman
5
passe à l’état ‘agressif’ lorsqu’il passe par une case qui contient un tonneau et dans ce cas boit
systématiquement une potion d’énergie à condition qu’il ne cumule pas en même temps au-delà de
3 potions actives. L’effet d’une potion bue devient inactif après 10 secondes. Il est possible de
cumuler des potions d’un même tonneau.
Les adversaires, quant à eux, sont dirigés aléatoirement à des fréquences périodiques. Ils vont
poursuivre le Pacman dans le labyrinthe. Les adversaires apparaissent dans la case "prison" où ils ne
font rien, puis sont libérés par la suite, chacun à son tour. En se libérant, l'adversaire passe à l'état de
‘recherche’ d'un Pacman. Dans ce cas, il se déplace de manière aléatoire à l'intérieur du labyrinthe.
Lorsque le Pacman est dans l’état ‘non agressif’ et se trouve dans un même couloir que l’adversaire,
ce dernier passe à l'état de ‘poursuite’ et son déplacement se fait dans la direction du Pacman dans
l’espoir de le rattraper. Par contre, l’adversaire va tenter de fuir le Pacman quand ce dernier est à
l’état ‘agressif’, jusqu’à ce que le Pacman passe à l’état ‘non agressif’. Quand un adversaire est
mangé par le Pacman, il va être replacé dans la "prison" et en ressortira après 2 secondes.
Après, l’analyse de ce jeu, un développeur a commencé une embauche de la conception et a proposé
le diagramme de classes UML incomplet suivant :
La méthode ‘MAJ ()’ de la classe 'Jeu' se charge de l’invocation des manœuvres
(déplacements et attaques) du ‘Pacman’ et celles des ‘Adversaires’ ainsi sue l’effet des
Advertisement
potions et ce à des fréquences périodiques.
La méthode ‘déplacer ()’ de la classe Occupant permet de déplacer l'occupant dans le
labyrinthe. Dans le cas de la classe Pacman, le joueur choisit la direction de déplacement en
l'indiquant comme paramètre dans la méthode ‘choisir’ et dans le cas de l'Adversaire, le
choix de la direction est automatique selon l'état de ce dernier.
La méthode ‘surUnMemeCouloir ()’ de la classe Adversaire permet de détecter la présence
du Pacman sur un même couloir (ligne ou colonne).
Les types ‘Direction’, ‘Etat_p’ et ‘Etat_adv’ sont des énumérations:
Direction= {immobile, haut, bas, droite, gauche}
Etat_p= {agressif, non agressif}
Etat_adv= {prisonnier, recherche, poursuite, fuite}
Travail à faire
On se propose de comprendre, compléter, améliorer la modélisation UML proposée par le
développeur.
6
Partie n°1 : Analyse
Question 1.1
Précisez les cardinalités manquantes des associations sur la portion de diagramme suivante :
Question 1.2
On se propose de promouvoir dans la mesure du possible les associations en compositions ou en des
agrégations. Cochez
bonne réponse pour chaque proposition en justifiant brièvement votre
réponse, puis reflétez ceci sur le diagramme de classes de la page précédente (question 1.1).
N’oubliez pas de proposez un nom à l’association s’il est impossible de la promouvoir : les classes
encadrées sont celles ayant la responsabilité de subordination
LA
Jeu- Labyrinthe: Association ………………. Composition X Agrégation
Justification: Appartenance totale+ cycles de vies dépendants
Case-Labyrinthe: Association ………………. Composition X Agrégation
Justification: Appartenance totale+ cycles de vies dépendants
Case-Tonneau: Association ………………. Composition Agrégation X
Justification: relation d’inclusion structurelle : Au moins une agrégation (la relation de composition
est aussi acceptable)
Jeu- Occupant: Association ………………. Composition Agrégation X
Justification: Appartenance faible : La durée d vie des agrégés est indépendante de celle de
l’agrégat. Il est possible de rattacher les agrégés à plus d’un agrégat
Case-Occupant: Association ………………. Composition Agrégation X
Justification: Appartenance faible
Pacman-Tonneau: Association X ………………. Composition Agrégation
Justification: Il n’y a pas la notion d’appartenance (ou de subordination)
7
Question 1.3
L’effet d’une potion bue dure pendant 10 secondes. Proposez une manière de représentation de
cette information dans le diagramme de classes. Commentez brièvement votre solution.
Une solution possible : Utilisation d’une classe associative
Question 1.4
Elaborez le diagramme d’objets conformément à vos réponses à la question (1.2) illustrant la
situation représentée par la figure ci-dessus
1
4
5
2
Advertisement
3
Adversaire et
Tonneau dans une
même Case
‘Simple’
Adversaire dans
une Case
"Prison"
1
2
3
4
5
Case
"Simple"
Pacman dans la
Case ‘Jocker’
Tonneau
Pour des raisons de clarté, on vous demande de représenter que les cases occupées. Nommez vos objets cases comme suit : ci,j (i est le n° de ligne et j
est le n° de colonne).
Partie 2 : Conception
Question 2.1
Afin de faciliter l’implémentation des associations, on se propose de limiter au maximum possible
la navigation. Précisez le sens de navigation sur le diagramme de classes en bas de page (Q2.2).
Question 2.2
Pour comprendre les règles de gestion gouvernant l’évolution des liens entre les objets, on se
propose de décorer les associations par les contraintes {ordered}, {addOnly}, {frozen},
{notUnique}.
8
a) Rappelez la signification de chaque contrainte de gestion :
Ordered: les éléments de la collection représentant le tissage des liens sont ordonnés
AddOnly : Il est possible de tisser de nouveaux liens mais impossible d’en supprimer
Frozen : le tissage des liens est fixé lors de la création et ne peut pas changer.
NotUnique : Il est possible d’avoir plus qu’un lien entre deux objets avec la même association
b) Décorez, directement sur le diagramme de classes ci-dessous, chacune des associations par
les contraintes de gestion appropriées. Vous pouvez tout simplement annoter le bout
navigable de chaque association par les symboles O, A, F, N (respectivement pour
(O)rdered, (A)ddOnly, (F)rozen et (N)otUnique).
Question 2.3
Donnez l’ordre de navigation sur les instances de classes concernées pour que :
1.
2.
la méthode ‘surUnMemeCouloir ()’ de la classe Adversaire puisse détecter la présence du
Pacman sur un même couloir (ligne ou colonne).
la méthode ‘déplacer()’de la classe Pacman puisse changer la position du Pacman
1. Adversaire- Case- Pacman-Case
2. Pacman -Case
Question 2.4
Pour des besoins d’optimisation, on se propose de changer la conception comme suit : L’association
entre le labyrinthe est la case devient de cardinalité ‘1’ et non plus ‘*’.
Donnez le nouvel ordre de navigation sur l’ensemble des objets concernées de la méthode
‘surUnMemeCouloir ()’.
Dans le cas de l’association qualifiée, le même ordre de navigation que précédemment.
Dans le cas de l’association réflexive : Adversaire-(Case)*-Pacman-Case
9