Cette page propose un diagramme de cas d’usage ainsi qu’un diagramme de classes pour l’entreprise de restauration en ligne de l’exercice 1 de la séance n°7.
Cette section montre une possibilité de cas d’usage.
Lorsqu’un client de ma petite entreprise de restauration arrive sur mon site, il peut le visiter, c’est-à-dire regarder les plats que l’entreprise propose. Il peut également se créer un nouveau compte, se connecter à un compte existant ou bien visualiser son panier actuel. Le lien <<extend>> entre la connexion et la création du compte correspond à l’idée suivante : si le client arrive sur le site et se connecte à un compte existant (qu’il avait créé lors d’une session précédente), on ne va pas lui demander de créer un nouveau compte. En revanche, s’il n’a pas encore de compte, il doit en créer un pour pouvoir se connecter. Donc, pour réaliser une connexion, éventuellement, on sera amené à créer un compte, d’où le <<extend>>.
Si les plats sont attractifs, le client passera commande. Dans ce cas, il aura forcément visité le site avant et choisi des plats. D’où le lien <<include>> entre la visite du site et la commande. Si le client n’est pas encore connecté, la page de commande lui demandera de le faire. Donc, pour pouvoir réaliser la commande, il faut obligatoirement être déjà connecté, d’où le lien <<include>> entre la commande et la connexion.
La commande va activer une activité de paiement. Celle-ci n’est pas demandée explicitement par le client : c’est la commande qui demande à ce que cette action soit réalisée. C’est pourquoi il n’y a pas de lien entre le client et le paiement. En revanche, puisque c’est la commande qui demande le paiement, la commande doit être appelée avant, d’où le lien <<include>> entre commande et paiement. Ce dernier peut être effectué par paypal ou par carte de crédit. Donc ces deux dernières actions sont des « sous-cas » de paiement, d’où les flèches d’héritage entre paiement d’une part, et paypal et carte de crédit d’autre part.
Le raisonnement est similaire pour les notifications.
En ce qui concerne le diagramme de classes, partons de l’acteur, notre client. Celui-ci va interagir avec le site de notre restaurant. Cela suggère de créer une première classe que l’on va appeler InteractionSite. Son objectif est d’afficher tout ce que l’acteur verra et de déclencher les opérations correspondant aux actions demandées par l’utilisateur (par exemple, quand l’utilisateur clique sur un bouton « commander », la page pour passer la commande est affichée, le paiement a lieu, etc.). Si l’on suit l’énoncé de l’exercice, on en déduit que cette classe sera abstraite et héritée par deux classes concrètes InteractionSiteWeb et InteractionSiteMobile car l’application doit être disponible sur ordinateur et sur smartphone. Est-ce que InteractionSite est une interface ou une classe abstraite ? Je dirais que c’est plutôt la deuxième solution car certaines méthodes peuvent être implantées exactement de la même manière sur smartphone et sur ordinateur : par exemple, les opérations à réaliser pour passer une commande sont précisément les mêmes. Donc autant les implanter une seule fois dans la classe InteractionSite.
La première des actions que l’on va envisager est celle de « visiter le site ». Quand on l’effectue, on visualise les plats disponibles dans le restaurant. Cela suggère de créer une classe Plat qui contient les informations sur un plat donné (une photo, son prix, son stock, une description, etc.). Grâce à une association entre les plats et l’interface du site, cette dernière peut afficher l’ensemble des plats disponibles. Pour l’instant, notre diagramme de classes ressemble donc à :
Note
Notez qu’entre InteractionSite et Plat, il est préférable d’utiliser une association plutôt qu’une composition. En effet, une composition signifie que InteractionSite est composée des Plats, qu’elle contient des Plats. Ce n’est pas très logique pour une interface utilisateur. Cette dernière a juste besoin d’interagir avec la liste des Plats, d’où une simple association.
Dans ce schéma, on peut déjà entrevoir un problème : InteractionSite interagit avec une liste de Plats. Mais comment celle-ci est-elle générée? On peut imaginer qu’on requête un serveur pour obtenir les données permettant de créer les plats. Et ce n’est clairement pas le rôle d'InteractionSite de le faire. Cela nous amène donc à créer une nouvelle classe GestionPlats qui aura pour but de créer les plats (initialiseµPlats()), de fournir des informations sur ceux-ci quand on lui en demandera (getPlatsEnStock()) et de mettre à jour le stock quand le client aura passé des commandes (diminueStockPlat()). Si on laisse l’attribut stock dans les Plat, n’importe quelle classe aura la possibilité de modifier le stock, ce qui n’est pas souhaitable étant donné que cela relève de la responsabilité de GestionPlats. On va donc placer l’information sur les stocks dans la classe GestionPlats :
En principe, quand on a une composition ou une agrégation, disons qu’une instance d’une classe A en contient un d’une classe B, on n’indique pas, parmi les attributs de la classe composite (A), celui correspondant à B. Ici, j’ai tout de même indiqué l’attribut plats pour que la structure de données contenant les plats soit bien claire.
Quand un plat paraît alléchant, l’acteur peut le mettre dans son panier. On va donc créer une classe Panier qui, elle aussi, va donc avoir une association avec InteractionSite, notamment parce que InteractionSite pourra récupérer les informations du Panier pour les afficher, pour demander d’ajouter ou supprimer un Plat. Le Panier n’a pas besoin d’interagir directement avec GestionPlats puisqu’il ne contient qu’une liste de Plats. En revanche, le Panier est constitué de Plats. Donc on va créer une relation d’agrégation entre ces deux classes. C’est une agrégation car les Plats existent en dehors du Panier. Cela nous amène au diagramme UML suivant :
On peut maintenant passer aux commandes. Pour les réaliser, on doit être connecté et, au préalable, avoir créé un compte. Cela suggère de créer une classe Client. Celle-ci a évidemment une association avec InteractionSite. Le client a également une association avec le Panier. Ici, une composition ne serait pas adaptée car, quand l’utilisateur surfe sur le site, il peut remplir son Panier avant de s’être connecté et, donc, avant que l’instance de client ait été créée. En revanche, une agrégation est adaptée car le client possède bien un Panier.
On peut maintenant réaliser la commande, via une classe qui va avoir besoin d’interagir avec le Client (pour obtenir son adresse, son email et son numéro de téléphone pour lui envoyer, éventuellement, un SMS). Il faut aussi récupérer le contenu du Panier mais, comme celui-ci est contenu par agrégation dans le Client, on n’a pas une nouvelle arête à rajouter. Enfin, quand la commande sera passée, il faudra mettre à jour le stock du restaurant, d’où une association avec GestionPlats. Pour l’instant (sans tenir compte des classes de paiement et de notification), on a donc :
Si l’on rajoute les classes de paiement et de notification, on obtient :