Un petit projet conçu avec UML et programmé en Java doit être réalisé dans le cadre de cet électif. Ce travail peut-être effectué en binôme (voir les modalités sur la page Edunao du cours).
Le sujet retenu est la réalisation d'une application permettant de jouer à un jeu de type Sokoban, un puzzle où il faut réussir à ranger des caisses sur des cases cibles d'un entrepôt.
L'objectif de cet exercice est de commencer la conception du modèle métier de cette application en utilisant UML. La fin de la conception puis la réalisation en Java de celle-ci seront faites en autonomie.
Cet exercice est principalement une activité de conception. Donc, et contrairement à l'exercice précédent :
- les attributs et rôles seront protégés ou privés ; les accesseurs et modifieurs nécessaires seront générés par l'outil ou ajoutés directement dans le code Java ;
- les opérations doivent être indiquées (on utilise pour les identifier les diagrammes de séquence) ;
- les associations seront initialement navigables dans les deux sens ; on supprimera ensuite les navigabilités non nécessaires ;
- les classes d'associations peuvent être utilisées au départ, mais il faudra les convertir en associations simples avant le fin de la conception.
Première conception des classes
- En vous basant sur la description du jeu sur la page Wikipédia, proposer une liste de classes possibles.
L'objectif est une réalisation en Java, nous utiliserons donc dès le départ les conventions de nommage de Java :
- les noms de classes commencent par une majuscule ;
- les noms d'attributs et de rôles commencent par une minuscule ;
camelCase
est utilisé.
Solution possible
Jeu
Entrepot
Case
ouZone
Mur
Caisse
Cible
ouDestination
ouRangement
Joueur
ouGardien
ouPersonnage
Niveau
Direction
- Créer avec Modelio un nouveau projet Sokoban.
- Créer un paquetage
entity
à l'intérieur du paquetagesokoban
, et un diagramme de classes dans ce paquetageentity
.

- Proposez un modèle avec classes, attributs et associations, en précisant les multiplicités des extrémités de celles-ci.
- Il n'est pas obligatoire de conserver toutes les classes possibles identifiées dans la question précédente ; par contre, vous pouvez être amené à introduire de nouvelles classes.
- L'auto-completion est disponible dans certains contextes (par exemple pour renseigner un type), il s'obtient avec
CTRL-Espace
.
Vous réfléchirez spécifiquement à une bonne représentation de la position des cases pour éviter une duplication d'information.
Solution possible

Préférer la solution de votre groupe de TD si elle diffère de celle-ci.
Ajout du contrôleur
Dans le cadre de la mise en œuvre du patron d'architecture MVC (Model-View-Controller) (qui sera vu plus tard), nous avons besoin d'une classe Controleur
; celle-ci servira d'intermédiaire entre les objets de l'interface homme-machine (IHM) et les objets métiers ; l'unique instance de cette classe recevra via l'IHM les demandes de l'utilisateur, et fournira à l'IHM les informations nécessaires à l'affichage de l'état du jeu.
- Créer un paquetage
control
à l'intérieur du paquetagesokoban
.
- Créer une classe
Controleur
à l'intérieur du paquetagecontrol
.
Vous pouvez directement créer des éléments de modélisation avec le menu contextuel dans la vue du modèle.
Les actions de jeu seront des demandes de déplacement du personnage dans une direction, nous représenterons les 4 directions possibles par une énumération.
- Créer une énumération
Direction
à l'intérieur du paquetageentity
, ajouter 4 litéraux correspondant aux 4 directions.
Par convention, les valeurs d'énumération en Java sont en majuscules.
L'IHM appellera une méthode du contrôleur pour l'informer des actions du joueur.
- Créer une opération
action(direction : Direction)
dans la classeControleur
.

- Quels objets le contrôleur doit-il connaître ? glisser-déposer la classe
Controleur
sur votre diagramme de classes, ajouter les associations correspondantes.
Solution possible
Le Controleur
doit connaître l'entrepôt pour afficher l'état du jeu, et le gardien pour lui transmettre les demandes de déplacement.
Les objets métiers ne doivent pas être impactés par l'existence de ce contrôleur, nous utiliserons donc ici des associations navigables dans un seul sens.
Conception du comportement
Le comportement est modélisé par les différentes opérations des classes. Pour identifier ces opérations, nous allons dérouler des séquences de jeu et les représenter dans des diagrammes de séquence.
Nous prendrons le jeu suivant comme base de scénarios :

Un diagramme de séquence permet de représenter des échanges de messages entre objets, nous avons donc besoin de nommer ceux-ci ; les zones nécessitent un nom spécifique pour les distinguer, nous utiliserons comme identifiants z_l0c0
à z_l4c5
de gauche à droite et de haut en bas.
Première action
- Créer un diagramme de séquence dans le paquetage
sokoban
.
- C'est l'IHM qui recevra les actions de jeu du joueur : créer une ligne de vie sur le diagramme de séquence pour représenter l'IHM.
- L'IHM transmet au contrôleur les demandes de mouvement : glisser-déposer sur le diagramme de séquence la classe
Controleur
pour créer une ligne de vie associée à l'unique instance de cette classe. - On suppose que la première action de jeu est une demande de déplacement à gauche : ajouter sur le diagramme un envoi de message synchrone de l'IHM vers le contrôleur ; préciser que l'opération associée est
action(direction : Direction)
et que l'argument estGAUCHE
.

Imaginons la suite du déroulement :
- Que fait le contrôleur quand il reçoit ce message ?
- Ce n'est pas lui qui doit examiner l'état du jeu pour décider si l'action de déplacement est possible ou non ; sa responsabilité est de vérifier que la demande d'action est autorisée, ce qui est le cas puisque le jeu n'est pas terminé.
- Le contrôleur doit donc transmettre la demande de déplacement à un objet métier, le gardien bien sûr.
On va traduire ce choix sur le diagramme de séquence :
- Glisser déposer la classe représentant le gardien sur le diagramme de séquence pour créer la ligne de vie correspondante.
- Ajouter le message synchrone.
- Créer l'opération correspondante ainsi que son paramètre.
- Associer le message synchrone à cette opération, préciser l'argument.
- Continuer à imaginer la suite des messages envoyés.
Vous devez essayer de jouer le rôle d'un objet qui reçoit un message : avez-vous dans vos attributs les informations permettant de répondre au service demandé : si oui, alors vous pouvez directement répondre ; si non, alors vous connaissez certainement un autre objet qui pourra répondre, au moins en partie : demandez-lui !
La « politesse » est une qualité qui est utile lors de la conception pour améliorer la modularité. Ainsi, ce n'est pas le gardien qui va regarder si une zone est libre pour s'y rendre, ou sinon essayer de la libérer en déplaçant la caisse… Au contraire, le gardien demandera à la zone si celle-ci est d'accord pour le recevoir ; la zone se chargera de voir si elle peut déplacer l'éventuelle caisse présente.
Actions suivantes
Quand ce premier scénario est terminé (vous serez peut-être amené à le modifier par la suite), faire un autre diagramme de séquence pour une demande de déplacement à droite, puis pour les autres situations (déplacement d'une caisse…).
Vous pouvez, dans Modelio, copier-coller des éléments de modélisation dans l'onglet Model
, y compris des interactions.

© 2024-25 CentraleSupélec