Master MIAGE Module : Génie Logiciel à Objets Intervenants : B. Delahaye & M. Bakhouya
TD N°5 : Langage OCL Objectifs :
Etudier via des exemples l’utilisation du langage OCL
Exercice 1 : retour sur le cours 1.1 Expliquer brièvement les notions d'agrégation et composition dans les diagrammes de classe. Quelle est la différence ? Donner un exemple de chaque. Agrégation : Une classe contient un ensemble d'objets d'une autre classe. Les objets existent indépendamment de l'agrégat. Exemple : Carnet de contacts/d'adresses. Composition : C'est une agrégation forte. Il y a un lien entre l'existence du composé et de ses composants. Exemple : Voiture/roues/moteur.
1.2 A quoi servent les diagrammes de composants lors de la modélisation UML d'un projet informatique ? Donner un exemple. Ils permettent d'exprimer le découpage modulaire d'une application et d'exprimer les dépendances fonctionnelles entre modules. Cela permet notamment de déterminer l'ordre de compilation. 1.3 Des sociétés emploient un ensemble de personnes, chacune d'elle ayant un poste dans ces société. Chaque poste est identifié par son type et le salaire correspondant. On distingue particulièrement les directeurs de chaque sociétés. Une même personne peut diriger plusieurs sociétés mais une société donnée n'est dirigée que par une personne. De même, chaque personne peut être employée par plusieurs sociétés. Les personnes sont identifiées par leur nom, leur prénom, leur genre et leur date de naissance. On souhaite de plus modéliser certains attributs de ces personnes, tels que leur age, leur revenu, s'ils sont mariés ou non et s'ils sont chômeurs ou non. On souhaite aussi modéliser les liens de parenté entre ces personnes (enfant/parent et mari/femme). Lorsque deux personnes sont mariées, la relation de mariage est identifiée par la date à laquelle il est survenu. Finalement, chaque personne possède des comptes en banques, qui peuvent éventuellement être partagés dans un couple. Ces comptes sont identifiés par leur numéro et leur solde (privé). Donner un diagramme de classe correspondant au système décrit ci-dessus. c.f. Ex 5.
1 TD N°5 : OCL
Exercice 2 Diagramme de classes Une entreprise souhaite informatiser la gestion de son parc informatique (ordinateurs, imprimantes, etc.) pour en optimiser la maintenance. Proposer un schéma de classes UML modélisant les spécifications ci-dessous (classes, associations entre classes, cardinalités des associations, attributs des classes). 1. Un ordinateur est caractérisé par son numéro d’inventaire, son adresse réseau (adresse IP), son modèle, la date de son acquisition, la date de la prochaine maintenance planifiée et le système d’exploitation installé. 2. Sur chaque ordinateur est installé un ensemble de logiciels caractérisés par un numéro de licence, un nom et une version. 3. Grâce à un système de mots de passe, chaque ordinateur peut être utilisé par plusieurs employés mais, pour des raisons de sécurité des données, un employé n’a le droit d’utiliser qu’un seul ordinateur. Un employé est caractérisé par son nom, son prénom et sa fonction dans l’entreprise. 4. Les ordinateurs sont reliés à un certain nombre de périphériques en réseau (imprimantes, scanners, etc.). Chaque périphérique est caractérisé par un numéro d’inventaire, son adresse IP, son type, son modèle, sa date d’acquisition et la date de la prochaine maintenance planifiée. Les périphériques pouvant servir à plusieurs ordinateurs simultanément, un indice de priorité est affecté à chaque ordinateur pour chaque périphérique auquel il est connecté. 5. Chaque ordinateur et chaque périphérique est localisé dans un bureau donné. Les bureaux sont caractérisés par un numéro de bureau et le numéro du bâtiment dans lequel ils se trouvent. Un numéro de bureau est unique dans un bâtiment donné.
2 TD N°5 : OCL
Exercice 3 Une entreprise souhaite modéliser avec UML le processus de formation de ses employés afin d’informatiser certaines tâches. Le processus de formation est initialisé quand le responsable formation reçoit une demande de formation d’un employé. Cet employé peut éventuellement consulter le catalogue des formations offertes par les organismes agréés par l’entreprise. Cette demande est instruite par le responsable qui transmet son accord ou son refus à l’employé. En cas d’accord, le responsable cherche la formation adéquate dans le catalogues des formations agréées qu’il tient à jour. Il informe l’employé du contenu de la formation et lui soumet le liste des prochaines sessions prévues. Lorsque l’employé à fait son choix il inscrit l’employé à la session retenue auprès de l’organisme de formation concerné. En cas d’empêchement l’employé doit avertir au plus vite le responsable formation pour que celui-ci demande l’annulation de l’inscription. A la fin de la formation l’employé transmet une appréciation sur le stage suivi et un document attestant sa présence. Le responsable formation contrôle la facture envoyée par l’organisme de formation. 3.1 Dessiner le diagramme des cas d’utilisation.
3 TD N°5 : OCL
3.2 Dessiner le schéma des classes de cette application, incluant toutes les classes que l’on peut déduire de l’énoncé, ainsi que les associations entre classes avec leurs cardinalités.
4 TD N°5 : OCL
3.3 Dessiner le diagramme de séquence associé à la demande initiale de l’employé décrite dans le deuxième paragraphe de l’énoncé ; assurer la cohérence avec votre réponse à la question précédente.
5 TD N°5 : OCL
Exercice 4 Le directeur d'une chaîne d'hôtels vous demande de concevoir une application de gestion de ses hôtels. Un hôtel est constitué d'un certain nombre de chambres (plus de 2). Un responsable de l'hôtel gère la location des chambres (on dira que cette personne dirige l'hôtel). Chaque chambre se loue à un prix donné. L'accès aux salles de bains est compris dans le prix de la location d'une chambre. Certaines chambres comportent une salle de bains, mais pas toutes. Les hôtes de chambres sans salle de bain peuvent utiliser une salle de bains sur le palier. Ces dernières peuvent être utilisées par plusieurs hôtes. Les pièces de l'hôtel qui ne sont ni des chambres ni des salles de bain (hall d'accueil, cuisine...) ne font pas partie de l'étude (hors sujet). Des personnes peuvent louer une ou plusieurs chambres d'hôtel afin d'y résider. Dans ce cas, on dit que l'hôtel héberge ces personnes. Un hôtel a pour attributs son adresse, le nombre de pièces qu'il contient, le numéro de l'étage inférieur et le numéro de l'étage supérieur. I faut pouvoir calculer le chiffre d'affaires de chaque hôtel. Une chambre a pour attributs son numéro, le nombre de lits qu'elle contient, son prix et son étage. On doit pouvoir repeindre une chambre avec une couleur choisie, ce qui engendre un coût (réel). Les salles de bains ont pour attributs leur étage, leur numéro, le nombre d'utilisateurs pouvant les utiliser, et on doit pouvoir les utiliser avec une fonction prenant en paramètre la personne concernée. Finalement, les personnes sont identifiées par leur nom, leur age et leur sexe. 4.1 Donner un diagramme de classes correspondant à cette spécification.
6 TD N°5 : OCL
Donnez une formulation en langage naturel pour chacune des contraintes OCL suivantes : 4.1 context Chambre inv : self.etage <>13 context SalleDeBains inv : self.etage <>13 Un hôtel ne contient jamais d'étage numéro 13 4.2 context Chambre inv : client->size <= nombreDeLits or (client->size = nombreDeLits +1 and client->exists(p:Personne | p.age < 4)) Le nombre de personnes par chambre doit être inférieur ou égal au nombre de lits dans la chambre louée. Les enfants (accompagnés) de moins de 4 ans ne comptent pas dans cette règle de calcul (à hauteur d'un enfant de moins de 4 ans maximum par chambre) 4.3 context Hotel inv : self.chambre->forAll (c : Chambre | c.etage <= self.etageMax and c.etage >= self.etageMin) L'étage de chaque chambre est compris entre le premier et le dernier étage de l'hôtel 4.4 context Hotel inv : Sequence{etageMin..etageMax}->forAll(i : Integer | if i<>13 then self.chambre->select(c : Chambre | c.etage = i)->notEmpty endif) Chaque étage possède au moins une chambre (sauf le 13 qui n'existe pas, bien entendu...) 4.5 context Chambre::repeindre(c:Couleur) pre : client->isEmpty post : prix = prix@pre * 1.1 On ne peut repeindre une chambre que si elle n'est pas louée. Une fois repeinte, une chambre coûte 10% de plus. 4.6 7 TD N°5 : OCL
context SalleDeBains::utiliser(p:Personne) pre : if chambre->notEmpty then chambre.client->includes(p) else p.chambre.etage = self.etage endif post : nbUtilisateurs = nbUtilisateurs@pre + 1 Une salle de bain privative ne peut être utilisée que par des personnes qui louent la chambre contenant la salle de bains et une salle de bains sur le palier ne peut être utilisée que par les clients qui logent sur le même palier 4.7 context Hotel::calculerLoyer() : integer post : result = self.chambre->select(client->notEmpty).prix->sum Le loyer de l'hôtel est égal à la somme du prix de toutes les chambres louées
Exercice 5 : Contraintes OCL Soit le diagramme de classes de la figure suivante qui modélise des personnes, leurs liens de parenté (enfant/parent et mari/femme) et le poste éventuel de ces personnes dans une société.
8 TD N°5 : OCL
Ajouter des contraintes pour les cas suivants : 1. Dans une société, le directeur est un employé, n’est pas un chômeur et doit avoir plus de 40 ans. De plus, une société possède exactement un directeur et au moins un employé context Société inv : self.directeur->size()=1 and not(self.directeur.chômeur) and self.directeur.age > 40 and self.employé->includes(self.directeur) 2. Une personne considérée comme au chômage ne doit pas avoir des revenus supérieurs à 100 € context Personne inv : let revenus : Real = self.poste.salaire->sum() in if chômeur then revenus < 100 else revenus >= 100 endif 3. Une personne possède au plus 2 parents (référencés). context Personne inv : parent->size()<=2 4. Si une personne possède deux parents, l’un est une femme et l’autre un homme. context Personne inv : parent->size()=2 implies ( parent->exists(genre=Genre::homme) and parent->exists(genre=Genre::femme) ) 5. Tous les enfants d’une personne ont bien cette personne comme parent et inversement. context Personne inv : enfant->notEmpty() implies enfant->forAll( p : Personne | p.parents->includes(self)) context Personne inv : parent->notEmpty() implies parent->forAll ( p : Personne | p.enfant->includes (self)) 9 TD N°5 : OCL
6. Pour être marié, il faut avoir une femme ou un mari. context Personne::marié derive : self.femme->notEmpty() or self.mari->notEmpty() 7. Pour être marié, il faut avoir plus de 18 ans. Un homme est marié avec exactement une femme et une femme avec exactement un homme. context Personne inv : self.marié implies self.genre=Genre::homme implies ( self.femme->size()=1 and self.femme.genre=Genre::femme) and self.genre=Genre::femme implies ( self.mari->size()=1 and self.mari.genre=Genre::homme) and self.age >=18
Exercice 6 : Soit une application bancaire permettant de gérer des comptes bancaires, des clients, et des banques. On souhaite intégrer les contraintes suivantes dans le modèle suivant: un compte doit avoir un solde toujours positif un client peut posséder plusieurs comptes une personne peut être cliente de plusieurs banques un client d’une banque possède au moins un compte dans cette banque un compte appartient forcément à un client une banque gère plusieurs comptes une banque possède plusieurs clients
Cependant, rien ne spécifie, dans ce diagramme, que le solde du client doit toujours être positif. On peut simplement ajouter une note précisant cette contrainte ({solde > 0}), comme le montre la figure suivant : 10 TD N°5 : OCL
Le diagramme d’objets suivant est valide vis-à-vis du diagramme de classes de la figure suivant mais ne respectant pas la spécification du problème. Ce diagramme d’objets montre une personne (P1) ayant un compte dans une banque sans en être client. Ce diagramme montre également un client (P2) d’une banque n’y possédant pas de compte.
Le diagramme de classes suivant accompagné des contraintes OCL est adapté à la spécification du problème. context Compte inv : solde > 0 context Compte :: débiter(somme : int) pre : somme > 0 post : solde = solde@pre - somme context Compte inv : banque.clients -> includes (propriétaire)
11 TD N°5 : OCL
Exercice 7 :
7.1 Donnez une expression OCL qui permette d'indiquer que la personne qui travaille dans le département est la même que celle qui est employée par l'entreprise. Cntext Personne inv : self.employeur = self.departement.employeur 7.2 Donner une expression OCL qui permette d'indiquer qu'une personne travaillant pour une entreprise doit être âgée de 18 ans et plus. On suppose que la classe Personne a un attribut âge. context Personne inv : self.age > 18 7.3 Modifier, graphiquement, le diagramme des classes précédent pour prendre en compte la contrainte suivante : context personne inv : (self.departement -> isEmpty) xor (self.Entreprise -> isEmpty)
12 TD N°5 : OCL
7.4 Ajouter la contrainte indiquant que deux personnes ne doivent pas avoir le même nom. Context Personne inv : Personne.allinstances -> forAll(p1,p2 | p1<>p2 implies p1.nom <> p2.nom) 7.5 Aucune personne n'est âgée de plus de 130 ans. Le jour d'anniversaire de la personne, son âge est augmenté de 1 an. Ajouter l'expression OCL permettant de représenter cette précondition et cette post-condition associées à l'opération anniversaire de Personne. context Personne : :anniversaire() pre : age >= 1 and age <130 post : age = age@pre +1 7.6 Les personnes qui travaillent dans l'entreprise sont âgées de 18 à 65 ans. Donner l'expression OCL correspondante. context Entreprise inv : self.employeur.forAll(Personne p | p.age >=18 and p.age <=65)
13 TD N°5 : OCL