Étude de cas UML : Jeu de Dés · Amélioration du découplage IHM / Noyau Introduction d’un...

Preview:

Citation preview

Étude de cas UML : Jeu de Dés

Étapes d’Analyse et Conception Démarche itérative

V. Deslandres IUT de Lyon, Université Lyon 1

Jeu de Dés   Il s’agit du jeu très simple afin qu’il puisse être traité

complètement.   Le joueur lance 10 fois deux dés.   A chaque fois que le total des deux dés fait 7, son

score est majoré de 10 points.   En fin de partie, le score final est inscrit dans un

tableau des scores.

  Cet exemple est tiré de :   l’ouvrage ‘Applying UML and Patterns’ de Craig

Larman   transparents de Jacques Lonchamp, du CNAM de

Nancy

Rappel Démarche UML (1/2)

 Analyse des Besoins   Cas d’utilisation   Diag. d’activités global

 Analyse   Premier diagramme de classes   Diag. de séquences   Diag. d’état

Enrichissement permanent,

vérification de la cohérence

Démarche UML (2/2)   Arrêt de l’analyse ?

  Etudier si les cas sont correctement couverts par l’analyse

  Conception   Architecture générale (couches)   Organisation en packages   Conception par niveau :

  Diagr. de classes partiels (classes techniques)   Ajouts des méthodes (accesseurs)   Diag. de séquences partiels

  Diag. de composants   Diag. de déploiement

Démarche : suite

 Génération du code (ici en Java)   Traduction des packages   Traduction des associations   Dernières améliorations

  Tests   Unitaires   Tests d’intégration   Tests d’acceptation auprès des users

Étape 1 : Analyse des Besoins

 Cas d’utilisation :

Diagramme d’activités global

Écran: Jeu de Dés Joueur : nom_joueur tour : 1

score : 0 dé1 : 5 dé2 : 4 lancer dés

Écran: Saisie Nom Joueur

Joueur : |

OK

Analyse des Besoins

 Vérification de cohérence   Les cas sont-ils bien traités dans le

diagramme d’activités ?

Étape 2 : Analyse

 Un premier diag. de collaboration

Quelle conséquence au niveau du diagramme de classes ?

OU

?

Analyse : 1er diag. de Classes

Vérification de cohérence

Analyse : diag. de séquences

Joueur réel Objet Joueur

Ici on complète l'analyse en modélisant la création des objets en début de partie.

le joueur n’est créé qu’au démarrage de la partie : c’est un choix qui découle du diagramme d’activités.

Alternative

 On aurait tout aussi bien pu créer le joueur au moment ou l’on crée le jeu   L’avantage de la modélisation choisie est

que l’on peut changer de nom entre 2 parties …

 Quelles seraient les modifications à effectuer sur les diagrammes ?

Analyse : diag. de séquences

Diagr. incomplet : ?

Ici le joueur est créé au début du jeu, avant le lancement de la partie : on aurait cette fois

plus d’une instance de PartieDés

Analyse : diagramme d’états

  Pour la classe PartieDés

Vérification de cohérence

?

?

Écran: Jeu de Dés Joueur : nom_joueur tour : 1

score : 0 dé1 : 5 dé2 : 4

Lancer les dés annuler

Modifications

Écran: Saisie Nom Joueur

Joueur : |

OK annuler

Arrêt de l’analyse ?

  Les cas d’utilisation sont-ils bien couverts par l’analyse ?

Cas ‘Consultation des Scores’ :

Traité

Cas ‘Jouer’ :

Traité sauf création scores

Modifications

  Intégrer la création et la gestion des scores   Créer une entrée au tableau des scores :

  Nom joueur, score obtenu

  On pourrait également affiner cette gestion en ne conservant que les 10 meilleurs scores par ex.

Diagramme de séquences MàJ

lancer()

lancer()

2ème diagramme de classes

ÉTAPE DE CONCEPTION Après l’analyse…

Étape 3: Conception

 Architecture générale en 3 couches

Application

Fichiers ou BD Persistance

Présentation

Écran: Jeu de Dés Joueur : nom_joueur tour : 1

score : 0 dé1 : 5 dé2 : 4

Lancer les dés annuler

Conception des packages

dépendance

Couche applicative ‘Noyau’  Objectif : mieux structurer les classes

issues de l’analyse  S’aider des design patterns

  Identifier le pattern Singleton :   Assure qu’une classe a une instance

unique, conservée dans une variable de classe (static uniqueInstance)

  Donne un point d’accès depuis la classe à cette instance (méthode de classe static getInstance() ).

Pattern Singleton

Singleton

static uniqueInstance

(Données du Singleton)

static getInstance()

(accesseurs données)

(méthodes Singleton)

Return uniqueInstance

Design pattern ‘Singleton’

  getInstance(): Singleton se charge d'automatiquement construire l’unique objet au 1er appel :

public Singleton getInstance(){ if (_instance == null) _instance = new Singleton();

return _instance; }

 Constructeur privé: private Singleton()

Passage Analyse / Conception + Ajout de méthodes : charger, enregistrer, afficher

2 singletons

Utilisation du Design pattern ‘Observer’ pour les vues sur Dé et Joueur

  Un objet (le sujet ou observable) est lié à plusieurs objets (les observateurs ou observers)   qui ne sont pas nécessairement connus à la création

du programme   Toute modification est répercutée (notified) à tous

les observateurs Observateurs

a=50% b=30% c=20%

sujet

Notification de changement

Requête, modification

Architecture du Pattern ‘Observer’

Utilisation du pattern Observer Sujets : dés et joueur (classe Observable)

Observateurs : les vues sur les dés

et sur les joueurs

Les vues sont des panneaux (composant AWT Java)

Écran: Jeu de Dés Joueur : nom_joueur tour : 1

score : 0 dé1 : 5 dé2 : 4

Lancer les dés annuler

Affichage des Observers

Enrichissement de la dynamique

Propagation d’un événement Ici propagation d’une nouvelle valeur pour un dé

Randomizer est une classe qui rend une valeur au hasard (pour le tirage du dé entre 1 et 6).

Conception du niveau interface utilisateur

Il faut définir les fenêtres graphiques (‘forms’) contenant éventuellement les panneaux vues.

Toutes les forms héritent de la classe awt Frame

Écran: Saisie Nom Joueur

Joueur : |

OK annuler

Écran: Jeu de Dés Joueur : nom_joueur tour : 1 score : 0

dé1 : 5 dé2 : 4 Lancer les dés Annuler

Mise en place de l’UI

Amélioration du découplage IHM / Noyau

Introduction d’un Interface Displayable

Objectif : rendre les 2

couches plus indépendantes

L’architecture en couches

Classes techniques de l’User Interface

Interfaces et classes abstraites de découplage

Classes applicatives du noyau

Niveau Persistance   Le stockage des scores peut se faire soit

par fichiers soit dans un SGBD   Pour assurer l’indépendance des couches

Noyau et Persistance, il faut gérer les deux types de persistance :   Fichiers sérialisation   SGBD tables

  Utilisation du pattern Factory   Qui permet la création d’instances de classes

distinctes via une unique interface

Utilisation du pattern Factory

Dynamique de la couche Persistance

Implémentation de la sérialisation

Implémentation de JDBC (1)

Implémentation de JDBC (2)

Remarque : highscore est une collection d’entrées (d’où le this.elements())

Diagramme de composants

Diagramme de déploiement

Implémentation en Java

Traduction Java des relations

Traduction Java des relations (2)

Conclusion   UML, utilisé conjointement avec un AGL,

  permet de documenter les choix d’analyse et de conception

  Grâce au processus de développement maîtrisé   le produit est conforme à ce qui était prévu au

départ   Grâce aux patterns, le produit est évolutif

  on peut facilement modifier l’interface ou la persistance

  Grâce à Java, le produit est portable   Système d’exploitation, SGBD

Recommended