UML est un ensemble de représentations graphiques permettant de modéliser des applications utilisant des langages à objet. Dans ce cours nous nous concentrerons sur les diagrammes de classes. Le diagramme de classe est l’adaptation du MCD aux classes, c’est-à-dire une représentation permettant de rapidement comprendre l’architecture d’une application. Son emploi est incontournable dès que l’on aborde des projets d’une certaine ampleur.
Pour lire ce document, il est nécessaire d’avoir quelques bases de Merise (première partie de ce cours) et de connaître les grands principes de la programmation objet (classe, instances, héritage, interfaces, etc.).
Une classe est représentée par une boîte contenant trois sections :
static
)
ainsi que les variables d’instance (non
static
).
L’exemple ci-dessus nous montre une classe Point disposant de deux attributs abscisse et ordonnée, tous deux de type double. Les quatre méthodes (les getter et les setter) se trouvent dans la troisième partie de la boîte.
La visibilité d’un identificateur est notée en le faisant précéder d’un
symbole + (
public
) ou - (
private
),
# (
protected
) ou ~ (
package
).
Un attribut est :
this
, vous ne pourrez pas vous en servir sur
un autre objet de la même classe.
Par exemple dans la classe Point ci-avant abscisse et ordonnée sont privés tandis que les quatre méthodes sont publiques.
Attention : Avec le logiciel que j’utilise, les attributs et méthodes statiques sont soulignés.
Lorsque deux classes sont reliées par une flèche, cela signifie que chaque instance de la classe se trouvant à l’extrémité initiale de la classe contient une référence vers une (ou plusieurs) instances de la classe se trouvant à l’extrémité finale de la flèche. Donc si flèche part de la classe A vers la classe B, on dit qu’il y a une relation de A vers B.
Cet exemple modélise l’inscription d’étudiants à des soirées. Un étudiant sera en correspondance avec les soirées auxquelles il est inscrit.
L’attribut de la classe située à l’extrémité initiale de la flèche servant à représenter la relation est très souvent précisé à côté de la flèche afin d’indiquer comment cette relation est implémentée. Pour éviter les redondances, on ne la précise pas avec les attributs de la classe.
Par exemple, mémoriser pour un étudiant l’ensemble des soirées auxquelles il est inscrit nécessite une variable (non-scalaire) appelée ici soirées.
Vous noterez que les sens des flèches indiquent un sens de navigation entre les objets. Si l’on a A —→ B, cela signifie qu’il est possible depuis un objet A de déterminer directement l’objet B qui est en relation avec. Vous noterez que la navigation dans l’autre sens ne sera pas facilité par cette spécification.
L’absence de flèche signifie que la navigation peut s’effectuer dans les deux sens. Cela peut être tout à fait pratique pour exploiter les classes, mais ce type de référence croisée peut être assez difficile à programmer.
La relation est ici bidirectionnelle, il est possible à partir d’un étudiant de retrouver les soirées et à partir des soirées de retrouver un étudiant.
Une relation peut être accompagnée d’un label étiquetant la nature de la relation, ce qui est apprécié lorsque cette dernière n’est pas évidente.
Les valeurs aux extrémités des flèches sont l’analogue des cardinalités en Merise. Sauf qu’elles sont à l’envers !
Vous remarquerez aussi que les notations peuvent être très hétérogènes :
Un étudiant peut s’inscrire à 0, une ou plusieurs soirées, tout comme à une soirée peut s’inscrire un nombre arbitraire d’étudiants. Par contre, une soirée ne peut se dérouler que dans un seul lieu, Le 0 signifiant qu’on se garde le droit de représenter des soirées dont le lieu n’a pas encore été déterminé. On notera que plusieurs soirées peuvent se dérouler dans le même lieu.
L’héritage est noté avec une flèche (quelques fois en pointillées) terminée par un triangle vide. La classe mère peut être une classe conventionnelle, une classe abstraite, ou encore une interface. On précise dans ce cas la nature de la classe mère afin d’éviter toute confusion. On prête aussi attention au fait que dans certains langages à objets, en particulier Java, l’héritage multiple est interdit.
Le cas particulier d’héritage qu’est l’implémentation se représente avec des flèches en pointillés.
Un objet de type Girafe sera aussi de type Equidé, de type Vertébré et enfin de type Animal.
Attention : Avec le logiciel que j’utilise, les classes et méthodes abstraites sont représentés en italique.
La composition est la notation utilisée pour transposer les entités faibles ou mondes objets. Une classe A est agrégée à une classe B si toute instance de A est reliée à une (et exactement une) instance de B, et ne peut donc pas exister sans cette instance de B. La composition implique qu’une instance de A sera toujours en relation avec la même la instance de B. On la note avec un losange noir du côté de la classe propriétaire.
Une commande sans client n’existe pas, la destruction du client entraîne la destruction de toutes ses commandes. Une fois crée, une commande sera toujours associée au même client.
Une classe A est l’agrégation d’une classe B lorsqu’une instance de A est une collection d’instances de B. On la représente avec un losange blanc du côté de la classe contenant la collection.
La différence avec une relation est simplement conceptuelle vu que dans les langages à objets, l’agrégation s’implémente de la même façon que si elle avait été représentée avec une relation plusieurs à plusieurs.
Une liste d’invités n’est qu’une classe pour regrouper des invités. Mais la disparition de la liste n’entraîne pas nécessairement la disparition des invités. C’est pour cela que dans le cas présent une agrégation à été préférée à la composition.
Dans le cas de relation plusieurs à plusieurs, il est fréquent que des valeurs accompagnent la relation. Dans les langages à objets, on n’a d’autres choix que de créer une classe spécialement pour ces valeurs. A chaque couple d’instances impliquées dans la relation correspond donc une instance de la classe d’association. La classe d’association est reliée avec des traits en pointillés à la relation.
Le fait qu’un produit figure sur une commande ne suffit pas à complètement caractériser leur relation. Il est nécessaire de disposer de la quantité de produit figurant sur cette commande. Comme cette quantité dépend à la fois du produit et de la commande, celle-ci ne peut figurer que dans une classe d’association.
Une relation ternaire est un ensemble de triplets mettant en relation trois objets. On l’écrit avec un losange relié aux classes de ces trois objets.
Une affectation concerne un enseignant, une matière et une classe. Ce qui signifie par exemple que chaque enseignant sera en correspondance avec des couples (matière/classe).
Lorsque chaque instance d’une classe contient une référence vers un objet du même type, on a afaire à une relation reflexive.
Chaque salarié possède un champ responsable référençant l’autre salarié qui est son supérieur hiérarchique.
Deux classes peuvent être reliées par plusieurs relations différentes.
Un étudiant peut aussi bien avoir organisé une soirée que s’y être inscrit (voire les deux). Les deux relations n’ont pas la même nature et il serait une erreur de les fusionner.
Construire un diagramme UML pour le cas Livraisons (vous utiliserez le MCD fait lors des cours précédents).
Nous souhaitons mettre au point un logiciel permettant de représenter un arbre généalogique. C’est à dire listage des personnes, mariages et filiation. Nous tiendrons compte le fait que les parents peuvent être inconnus. Par contre, nous ne gérerons que les mariages hétérosexuels et nous ferons abstractions de certains pratiques en vogue comme la transexualité (si vous êtes sages nous ferons un TP là-dessus plus tard dans l’année). Représentez cette situation avec un MCD.
Nous souhaitons gérer une bibliothèque simple. Nous recenserons une liste d’ouvrages, avec pour chacun le titre et l’auteur (éventuellement plusieurs). On tiendra compte du fait que des ouvrages peuvent exister en plusieurs exemplaires, certains pouvant ne pas être disponibles pour le prêt (consultables uniquement sur place, ou détruits). Une liste d’adhérents devra être tenue à jour, les adhésions devant se renouveler une fois par an. Il devra être possible de vérifier qu’une adhésion est à jour (c’est-à-dire qu’elle a été renouvelée il y a moins d’un an), mais il ne sera pas nécessaire de connaître l’historique des renouvellements. Les adhérents peuvent emprunter jusqu’à 5 livres simultanément et chaque livre emprunté doit être retourné dans les deux semaines. On devra conserver un historique permettant de savoir quel abonné a emprunté quels livres, les dates d’emprunts et de retours.
Nous souhaitons gérer des comptes en banque. Une liste de comptes, avec numéro et libellé doit être tenue à jour. On souhaitera connaître pour chacun d’eux l’identité du propriétaire du compte (sachant qu’un compte peut dans certains cas appartenir à plusieurs personnes). Pour chaque compte, on conservera l’historique des modifications (virement, retrait, dépôt). On considérera comme un virement tout opération impliquant deux comptes et comme des retraits (ou dépôts) toute opération n’impliquant qu’un seul compte.
Une ligue sportive souhaite informatiser les inscriptions à des compétitions. Chaque compétition porte un nom et une date de clôture des inscriptions. Selon les compétitions, les candidats peuvent se présenter seul ou en équipe, sachant que le détail des équipes (liste des candidats et entraîneur) devra aussi être géré.
Nous souhaitons gérer un CMS (content management system). Un CMS est un logiciel permettant de gérer le contenu d’un ou plusieurs sites web. Chaque site porte un nom, est caractérisé par une URL, et est découpé en catégories, imbricables les unes dans les autres. Des utilisateurs sont répertoriés dans le CMS, et chacun peut avoir le droit (ou non) d’écrire dans un site web. Chaque utilisateur doit avoir la possibilité de publier des articles (ou des brèves) dans une catégorie d’un site web (pourvu qu’il dispose de droits suffisants dessus). Une brève est composée d’un titre et d’un contenu textuel. Un article, en plus de son titre et de son texte d’introduction, est constitué de chapitres portant chacun un nom et contenant un texte. Il va de soi qu’on doit avoir la possibilité pour chaque site de conserver l’historique de quel article (ou brève) a été publié par quel utilisateur. Réalisez un diagramme de classes modélisant cette situation.