Série N°3: Modélisation structurelle UML

Correction de l'exercice 1 - Application de calcul d'itinéraires Question 1.a - Type particulier d'association Le type particulier d'association remarqué dans le diagramme proposé par le développeur est l' association unidirectionnelle . Sa définition est la suivante : il s'agit d'une association où la navigation s'effectue dans un seul sens (indiqué par une flèche ouverte).

D'après le document Série N°3: Modélisation structurelle UML

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Série N°3: Modélisation structurelle UML

Document source

Série N°3: Modélisation structurelle UML

Informatique, Robotique · École Nationale des Sciences de l'Informatique (ENSI) · PDF · 9 pages · 2015

Afficher l'aperçu du document

Consulter le document original →

Correction de l'exercice 1 - Application de calcul d'itinéraires

Question 1.a - Type particulier d'association

Le type particulier d'association remarqué dans le diagramme proposé par le développeur est l'association unidirectionnelle. Sa définition est la suivante : il s'agit d'une association où la navigation s'effectue dans un seul sens (indiqué par une flèche ouverte). L'objet source a connaissance de l'objet cible, mais la réciproque n'est pas vraie.

Question 1.b - Signification des associations

D'après le diagramme proposé, voici la signification de chaque association :

  • Grille-Robot (habitant) : Une grille peut contenir 0 ou plusieurs habitants de type robot.
  • Grille-Case (Obstacle) : Une grille contient 0 ou plusieurs obstacles, qui sont représentés par le type Case.
  • Itineraire-Case (départ) : Un itinéraire possède une et une seule case de départ.
  • Itineraire-Case (arrivée) : Un itinéraire possède une 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.

Question 2 - Diagramme d'objets de la zone géographique

L'énoncé fait référence à une figure géométrique qui n'a pas pu être extraite dans le texte fourni, mais nous en connaissons les éléments : 1 zone géographique, 7 obstacles, et 1 robot nommé Zulu. Les conventions de coordonnées sont (x, y) avec (0,0) en haut à gauche.

Puisqu'un rendu graphique UML est impossible ici, voici la modélisation sous forme d'instances et de liens. Chaque instance est soulignée dans un diagramme UML classique.

Instances créées :

  • z : Grille (la zone géographique)
  • zulu : Robot
  • o1 : Case, o2 : Case, ..., o7 : Case (les 7 obstacles, avec leurs coordonnées x,y respectives)
  • cd : Case (la case de départ)
  • ca : Case (la case cible/arrivée)

Liens tissés entre les instances :

  • Un lien habitant relie l'instance z à l'instance zulu.
  • Sept liens Obstacle relient l'instance z aux instances o1 à o7.
  • Note : Zulu se trouve initialement sur la case de départ cd. Selon le modèle actuel, le robot ne pointe pas directement vers la case de départ, il faut donc s'en tenir aux associations définies (Grille contient Robot et Obstacles).

Question 3.a - Reflet de la modification sur le modèle UML

Pour refléter la modification permettant le calcul d'un itinéraire :

  1. Classe Robot :
    • On ajoute un attribut privé : - zoneDuRobot : Grille* (un pointeur ou une référence vers l'objet Grille).
    • On ajoute une méthode publique : + presenceObstacle(x: Entier, y: Entier) : Booléen.
  2. Association Robot-Grille :
    • Puisque le robot possède maintenant un pointeur explicite vers la grille (zoneDuRobot), l'association entre Robot et Grille devient navigable dans le sens Robot -> Grille, ou bidirectionnelle si la grille garde la trace de ses habitants.

Question 3.b - Reconnaissance des obstacles par un Itinéraire

Non, une instance de la classe Itineraire ne peut pas reconnaître les obstacles. Justification : À partir d'une instance Itineraire, la navigation UML ne permet de joindre que la case de départ, la case d'arrivée et les cases visitées (le chemin). À partir d'une Case, il n'y a aucune visibilité sur le reste de la grille ni sur les obstacles. La seule classe possédant une visibilité sur les obstacles est la classe Grille (et par extension, la classe Robot grâce à sa nouvelle association vers la grille).

Question 4.a - Signification des contraintes de gestion

  • frozen : Le tissage des liens est fixé définitivement lors de la création de l'objet et ne peut plus être modifié par la suite (immuabilité du lien).
  • addOnly : Il est possible de tisser de nouveaux liens (ajouter des éléments), mais il est impossible d'en supprimer.
  • ordered : Les éléments de la collection qui représentent le tissage des liens multiples sont ordonnés (l'ordre d'insertion ou un ordre logique compte).
  • notUnique : Il est possible d'avoir plus d'un lien entre deux mêmes objets pour la même association (les doublons sont autorisés).

Question 4.b - Décoration des associations par les contraintes

  • Grille-Robot (habitant) : Aucune contrainte spécifique n'est mentionnée (le robot se déplace, entre ou sort, donc la collection évolue librement).
  • Grille-Case (Obstacle) : {frozen} (l'énoncé précise que le nombre et la position des obstacles sont connus à l'avance et fixes).
  • Itineraire-Case (départ) : {frozen} (la case de départ reste inchangée).
  • Itineraire-Case (arrivée) : {frozen} (la case d'arrivée reste inchangée).
  • Itineraire-Case (chemin) : {notUnique, addOnly, ordered} (une case peut être visitée plusieurs fois, on construit l'itinéraire étape par étape sans effacer le passé, et l'ordre des étapes forme le chemin).

Question 4.c - Impact des contraintes sur les méthodes des classes

  • frozen : L'initialisation du lien doit obligatoirement se faire au niveau du constructeur de la classe. Aucune méthode "set" ou de modification ne doit être exposée.
  • notUnique : L'implémentation doit prévoir un moyen de distinguer deux liens identiques pointant vers le même objet (par exemple, en permettant les doublons dans une liste au lieu d'un ensemble (Set), ou en dupliquant les objets).
  • addOnly : La classe doit exposer des méthodes d'ajout (ex: add(), insert()), mais aucune méthode de suppression (ex: remove(), clear()) ne doit être implémentée.
  • ordered : L'implémentation doit conserver un ordre, ce qui implique de recourir à un chaînage entre les éléments ou de maintenir un index explicite (ex: List en Java, et non un HashSet).
  • Sans contraintes : La classe doit fournir l'ensemble complet des accesseurs et mutateurs (add, remove, insert, update).

Question 4.d - Choix des structures de données pour les collections

  • Grille-Robot (habitant) : Il n'y a aucune contrainte de taille fixe ou d'ordre. Le nombre de robots n'est pas connu à l'avance. Le choix optimal est une liste simplement ou doublement chaînée (une liste simplement chaînée suffit puisqu'on ne requiert pas de parcours inversé complexe).
  • Grille-Case (Obstacle) : La taille n'est pas une constante absolue pour toutes les grilles (on écarte le tableau statique natif). Cependant, cette taille est figée lors de la construction de la grille. Un tableau dynamique pourrait convenir. Toutefois, comme la grille ne connaît pas forcément le nombre d'obstacles avant son instanciation complète, le corrigé recommande d'utiliser une liste simplement chaînée.
  • Itineraire-Case (chemin) : La taille de l'itinéraire (le nombre de pas) n'est pas connue à priori. L'ordre est fondamental pour conserver la succession des cases visitées, mais aucun parcours bidirectionnel n'est strictement exigé. Le choix logique est donc une liste simplement chaînée.

Question 5 - Déplacement de l'opération "presenceObstacle"

Oui, il est tout à fait possible et même recommandé de déplacer l'opération presenceObstacle vers la classe Grille. Justification : La classe Grille est l'expert en information (principe GRASP) responsable des obstacles. C'est elle qui détient la collection des cases marquant les obstacles. Lui déléguer cette méthode améliore la cohésion et évite au robot d'avoir à manipuler directement les données internes de la grille.

Question 6 - Mémorisation des itinéraires par Robot

Non, avec la modélisation actuelle et l'association habitant entre Grille et Robot, il est impossible de mémoriser les itinéraires. Justification : Le diagramme ne fournit aucun chemin de navigation permettant de joindre un Robot à un objet Itineraire. La méthode de calcul de l'itinéraire dans Robot se contente de renvoyer l'objet (return), mais ne le stocke pas. Solution proposée : Il faut créer une nouvelle association directe entre Robot et Itineraire avec une cardinalité [1 - *] (un robot peut avoir calculé plusieurs itinéraires). Si l'itinéraire dépend strictement du contexte d'une grille donnée, on peut promouvoir la classe Grille en tant que classe d'association de cette nouvelle relation.

Question 7 - Intégration de la classe Application (Agrégation vs Composition)

Définitions :

  • Agrégation : C'est une relation d'inclusion (structurelle ou comportementale) de type "ensemble/élément" où l'élément (agrégé) a une durée de vie indépendante de l'ensemble (agrégat). Un agrégé peut être partagé entre plusieurs agrégats.
  • Composition : C'est une agrégation forte traduisant une contenance structurelle stricte. L'objet composant ne peut appartenir qu'à un seul composite, il ne peut pas exister sans lui, et la destruction du composite entraîne invariablement la destruction de ses composants.

Nouveau modèle : La classe Application agit comme le composite principal.

  • Application aura une relation de composition vers Grille (l'application gère le cycle de vie de la grille).
  • Application aura une relation de composition vers les objets de base Case.
  • Les objets Robot pourraient faire l'objet d'une agrégation par l'Application (ou la Grille), s'ils peuvent exister indépendamment d'une partie.

Correction de l'exercice 2 - Jeu Pacman

Question 1.1 - Cardinalités manquantes

Note : Le schéma n'étant pas visuellement disponible, les cardinalités sont déduites des règles de gestion énoncées.

  • Labyrinthe - Case : 1 ----- 1..* (un labyrinthe est composé d'un ensemble de cases n×m).
  • Case - Tonneau : 1 ----- 0..1 (chaque case contient au plus un tonneau).
  • Case - Occupant : 1 ----- 0..* (une case peut abriter un nombre quelconque d'occupants).
  • Occupant - Case : 0..* ----- 1 (un occupant est positionné sur une et une seule case à un instant t).

Question 1.2 - Promotion des associations (Agrégation / Composition)

  • Jeu - Labyrinthe : Composition. Justification : Appartenance totale et cycles de vie dépendants (le labyrinthe n'existe pas en dehors d'une partie de jeu).
  • Case - Labyrinthe : Composition. Justification : Appartenance totale et cycles de vie dépendants (les cases constituent structurellement le labyrinthe).
  • Case - Tonneau : Agrégation (ou Composition acceptable). Justification : Relation d'inclusion structurelle. Le tonneau est posé sur la case, mais conceptuellement, il pourrait être vu comme un objet distinct.
  • Jeu - Occupant : Agrégation. Justification : Appartenance faible. La durée de vie des occupants (Pacman, Adversaires) est indépendante du cycle de l'objet Jeu (ils peuvent être instanciés avant le lancement de la partie).
  • Case - Occupant : Agrégation. Justification : Appartenance faible et temporaire (les occupants se déplacent d'une case à l'autre).
  • Pacman - Tonneau : Association simple (à nommer par exemple : "Boire"). Justification : Il n'y a aucune notion d'appartenance structurelle ou de subordination, juste une interaction.

Question 1.3 - Représentation de l'effet d'une potion (10 secondes)

Solution proposée : L'utilisation d'une classe associative (par exemple nommée EffetPotion) liée à l'association entre Pacman et Tonneau. Commentaire : La durée active d'une potion est une propriété qui n'appartient ni au Pacman (qui peut en cumuler plusieurs avec des temps différents), ni au Tonneau (qui a une capacité infinie). La classe associative porte l'attribut tempsRestant (initialisé à 10s) ou le timestamp de consommation, permettant de gérer les 3 potions actives simultanément.

Question 1.4 - Diagramme d'objets (Situation du jeu)

Sur la base des coordonnées extraites de l'énoncé :

  • c1_4 : Case (Simple)
  • c2_2 : Case (Prison)
  • c5_4 : Case (Jocker)
  • a1 : Adversaire
  • a2 : Adversaire
  • p : Pacman
  • t1 : Tonneau

Liens instanciés :

  • L'adversaire a1 et le tonneau t1 sont liés à la case c1_4 (Agrégation Case-Occupant et Case-Tonneau).
  • L'adversaire a2 est lié à la case c2_2 (Prison).
  • Le Pacman p est lié à la case c5_4 (Jocker).

Question 2.1 - Sens de navigation

Pour limiter la navigation, on privilégie une structure hiérarchique descendante, du conteneur vers le contenu : Jeu → Labyrinthe → Case → Occupant (et Tonneau). L'occupant n'a pas nécessairement besoin de naviguer vers le Jeu, mais doit pouvoir identifier sa Case courante.

Question 2.2 - Contraintes de gestion des associations

a) Significations :

  • Ordered (O) : Collection ordonnée.
  • AddOnly (A) : Ajout autorisé, suppression interdite.
  • Frozen (F) : Lien immuable après sa création.
  • NotUnique (N) : Doublons autorisés dans le tissage des liens.

b) Décorations (Déduction métier) : Bien que l'énoncé source ne donne pas le corrigé textuel explicite pour ce point, le contexte du jeu impose logiquement :

  • Labyrinthe → Case : {Frozen} (F) (la géométrie du labyrinthe ne change pas en cours de jeu).
  • Case → Tonneau : {Frozen} (F) (les tonneaux ne changent pas de place).
  • Case → Occupant : Aucune contrainte restrictive, car les occupants entrent et sortent librement des cases.

Question 2.3 - Ordre de navigation pour les méthodes

  1. Méthode surUnMemeCouloir() (Classe Adversaire) : L'ordre de navigation est : Adversaire → Case → Pacman → Case. (Note métier : L'adversaire vérifie les coordonnées de sa propre case, puis obtient le Pacman du Jeu/Labyrinthe, et vérifie la case du Pacman pour comparer les numéros de lignes ou de colonnes).
  2. Méthode déplacer() (Classe Pacman) : L'ordre de navigation est : Pacman → Case. (Le Pacman interroge sa case actuelle pour identifier et rejoindre une case voisine).

Question 2.4 - Optimisation : Labyrinthe et Case de cardinalité '1'

Si l'association Labyrinthe-Case devient de cardinalité 1 au lieu de * (ce qui implique une matrice via une association qualifiée par [x,y] ou une association réflexive entre cases type maillage réseau) :

  • Dans le cas d'une association qualifiée : L'ordre de navigation reste le même que précédemment (Adversaire → Case → Pacman → Case), mais l'accès aux cases se fait en O(1) via les coordonnées.
  • Dans le cas d'une association réflexive (maillage) : L'ordre de navigation devient Adversaire → (Case)* → Pacman → Case. On navigue de proche en proche d'une case à sa voisine dans une boucle sur la ligne ou la colonne courante jusqu'à trouver ou non le Pacman.

Méthode

Face à un examen de modélisation orientée objet et UML structurel, suivez toujours ce processus :

  1. Lisez exhaustivement les règles de gestion : Les indices cruciaux sur les associations (Agrégation vs Composition) se cachent dans les verbes et le vocabulaire de durée de vie ("fixe", "détruit", "composé de").
  2. Tracez la dépendance de vie : Si un élément perd son sens ou doit être supprimé quand son conteneur disparaît, c'est une Composition. Si l'élément peut exister isolément ou changer de propriétaire, c'est une Agrégation (ou une association simple).
  3. Vérifiez la navigation : Demandez-vous "Cet objet A a-t-il besoin d'invoquer les méthodes de l'objet B pour réaliser son traitement ?". Si oui, le lien doit être navigable de A vers B. L'ajout d'une navigabilité non justifiée surcharge inutilement le couplage.
  4. Justifiez par le principe d'expert en information : Lors du placement d'une méthode (comme presenceObstacle), affectez la responsabilité à la classe qui détient les données requises pour accomplir le travail.
  5. Ne forcez pas les données manquantes : Si l'énoncé vous demande de dessiner une figure sur la base d'un schéma non imprimé (comme pour la Question 1 de l'Exercice 2), documentez clairement vos hypothèses de coordonnées (x,y) de manière à prouver la validité de votre raisonnement logique.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions