Diagramme structurel · UML 2.x

Diagramme
de Classes

Modélise la structure statique d'un système : classes, attributs, méthodes, et les relations entre elles.

📐 Structure statique 🔗 Relations 🔢 Multiplicités 🐍 Vers Python
«abstract» Véhicule - marque : String - vitesse : int + demarrer() : void + decrire() : String Voiture - nbPortes : int + decrire() : String Moteur - cv : int + getCv() : int 1 Héritage Compo.

Représentation d'une Classe

Une classe UML est représentée par un rectangle divisé en 3 compartiments : le nom, les attributs, et les méthodes.

Personne - nom : String - age : int = 0 # email : String + getNom() : String + setAge(a:int) : void - valider() : bool ① Nom ② Attributs ③ Méthodes

Conventions de nommage

ÉlémentSyntaxe & convention
Nom de classePascalCase, singulier, centré. Abstraites en italique.
Attributvisibilité nom : Type = valeurDéfaut
Méthodevisibilité nom(p:Type) : TypeRetour
Statiquesouligné — partagé par toutes les instances
Abstraititalique — doit être implémenté
💡

Un compartiment vide peut être omis. On peut ajouter un 4ᵉ compartiment pour les contraintes ou stéréotypes.

Visibilité

Chaque attribut et méthode est précédé d'un symbole indiquant son niveau d'accès.

SymboleNomAccèsPython
+ PublicTout le mondeattribut
- PrivéClasse uniquement__attribut
# ProtégéClasse + sous-classes_attribut
~ PackageMême package/moduleconvention

Classe Abstraite & Membres Statiques

Une classe abstraite ne peut pas être instanciée directement. Son nom et ses méthodes abstraites sont en italique. Les membres statiques (partagés par toutes les instances) sont soulignés.

Nom de classe en italique (ou stéréotype «abstract»)
Méthodes abstraites en italique — à implémenter par les sous-classes concrètes
Peut contenir des méthodes concrètes
Membres soulignés = statiques, partagés par toutes les instances
📌

En Python : class C(ABC) pour abstrait, @abstractmethod pour méthodes abstraites. Membre statique = attribut de classe ou @classmethod.

«abstract» Forme # couleur : String = "noir" + nbFormes : int = 0 souligné + aire() : float italique + getCouleur() : String + getNbFormes() : int statique
Python
from abc import ABC, abstractmethod

class Forme(ABC):           # abstraite
    nb_formes = 0            # statique

    def __init__(self, couleur="noir"):
        self._couleur = couleur  # protégé #
        Forme.nb_formes += 1

    @abstractmethod
    def aire(self) -> float: ...  # abstraite

    def getCouleur(self):     # concrète
        return self._couleur

    @classmethod
    def getNbFormes(cls):     # statique
        return cls.nb_formes

Interface

Une interface définit un contrat pur : uniquement des signatures de méthodes, sans implémentation. Une classe peut implémenter plusieurs interfaces.

Stéréotype «interface» obligatoire
Toutes les méthodes sont publiques et abstraites
Pas d'attributs d'instance (seulement des constantes)
Relation de réalisation : flèche pointillée + triangle creux
Classe abstraite
Peut avoir du code, des attributs
VS
Interface
Contrat pur, pas d'état
«interface» Serialisable + serialiser() : String + deserialiser(s:str) Document - contenu : String + serialiser() : String «realize»
Python
from abc import ABC, abstractmethod

class Serialisable(ABC):  # «interface»
    @abstractmethod
    def serialiser(self) -> str: ...

    @abstractmethod
    def deserialiser(self, s: str): ...

class Document(Serialisable):
    def serialiser(self):
        return self.contenu
    def deserialiser(self, s):
        self.contenu = s

Réalisation multiple

Une classe peut implémenter plusieurs interfaces simultanément — c'est l'un des grands avantages des interfaces.

«interface» Affichable + afficher() : void «interface» Sauvegardable + sauvegarder() : void Rapport + afficher() : void + sauvegarder() : void

Stéréotypes & Annotations

Les stéréotypes précisent le rôle ou la nature d'un élément UML. Ils sont écrits entre guillemets « ».

«abstract»

Classe qui ne peut pas être instanciée. Peut s'exprimer par le nom en italique.

«abstract»
Animal
+ parler() : void
«interface»

Classe purement abstraite définissant un contrat. Toutes les méthodes sont abstraites.

«interface»
Comparable
+ compareTo(o) : int
«enumeration»

Type énuméré. Liste un ensemble de valeurs constantes nommées.

«enumeration»
Couleur
ROUGE
VERT
BLEU
«utility»

Classe utilitaire : uniquement méthodes statiques. Pas destinée à être instanciée.

«utility»
MathUtils
+ arrondir(n) : float
+ max(a,b) : int
«singleton»

Une seule instance possible. Constructeur privé, accès via méthode statique.

«singleton»
Config
- instance : Config
- Config()
+ getInstance() : Config
«dataType»

Type de donnée structuré (ex: Date, Point) sans comportement complexe.

«dataType»
Point
+ x : float
+ y : float

Stéréotypes personnalisés

On peut créer ses propres stéréotypes pour documenter l'architecture :

«controller» — classe gérant la logique métier (MVC)
«repository» — classe d'accès aux données
«service» — classe de service applicatif
«entity» — classe représentant une entité persistante
«factory» — classe responsable de la création d'objets

Vue d'ensemble des Relations

Les classes sont reliées entre elles par 5 types de relations principales, chacune avec une notation graphique précise.

Relation
Notation
Signification
Association
"utilise" — lien simple entre classes
Agrégation
◇ "a un" — losange vide côté tout, partie indépendante
Composition
◆ "composé de" — losange plein, cycle de vie partagé
Héritage
"est un" — triangle creux vers le parent
Réalisation
"implémente" — pointillé + triangle creux (vers l'interface)
Dépendance
"dépend de" — flèche pointillée pleine, lien temporaire

Association

L'association exprime qu'une classe connaît ou utilise une autre classe. C'est le lien le plus général.

Représentée par une ligne simple avec flèche optionnelle
Peut être nommée pour clarifier le sens
La flèche indique le sens de navigation
Sans flèche = association bidirectionnelle
💡

Un Étudiant est inscrit dans un Cours. L'étudiant « connaît » ses cours, mais pas nécessairement l'inverse.

Étudiant - nom : String - matricule : int Cours - intitule : String - credits : int est inscrit
Python
class Etudiant:
    def __init__(self, nom):
        self.nom = nom
        self.cours = []  # association

    def inscrire(self, cours):
        self.cours.append(cours)

Agrégation

L'agrégation est une association spéciale « tout–partie ». La partie peut exister sans le tout.

Losange vide côté « tout »
La partie a une vie indépendante
Si le tout est détruit, la partie continue d'exister
🔎

Une Équipe est composée de Joueurs. Si l'équipe se dissout, les joueurs existent toujours.

Équipe - nom : String + jouer() : void Joueur - nom : String - numero : int 1 1..*
Python
class Equipe:
    def __init__(self, nom):
        self.nom = nom
        self.joueurs = []  # agrégation

    def ajouter(self, joueur):
        # joueur existe en dehors d'Equipe
        self.joueurs.append(joueur)

Composition

La composition est une agrégation forte : la partie ne peut exister sans le tout. Leur cycle de vie est identique.

Losange plein côté « tout »
La partie est créée par le tout
Si le tout est détruit, la partie l'est aussi
La partie n'appartient qu'à un seul tout
Agrégation ◇
Partie indépendante — peut être partagée
VS
Composition ◆
Partie liée — détruite avec le tout
Maison - adresse : String + getAdresse() : str Pièce - superficie : float - type : String 1 1..n
Python
class Maison:
    def __init__(self, adresse, nb):
        self.adresse = adresse
        # pièces créées DANS Maison
        self.pieces = [
            Piece(f"Pièce {i}")
            for i in range(nb)
        ]

Héritage (Généralisation)

L'héritage indique qu'une classe est une spécialisation d'une autre. La flèche pointe vers le parent (la classe la plus générale).

Flèche avec triangle creux vers le parent
L'enfant hérite tous les membres du parent
L'enfant peut redéfinir (override) des méthodes
Relation « est-un » (is-a)
🎯

Ne pas répliquer les attributs hérités dans l'enfant ! Un Cercle hérite de couleur depuis Forme — inutile de le réécrire.

«abstract» Forme # couleur : String Cercle - rayon : float + aire() : float Rectangle - largeur : float - hauteur : float

Dépendance

La dépendance indique qu'une classe utilise temporairement une autre, sans la posséder. C'est le lien le plus faible.

Flèche pointillée avec pointe pleine
Souvent via un paramètre de méthode
Ou une variable locale temporaire
Pas de référence persistante (pas d'attribut)
💡

Une Imprimante dépend d'un Document pour sa méthode imprimer(doc) — mais ne le stocke pas.

Imprimante + imprimer(d:Doc) : void Document - contenu : String + getContenu() : str «use»
Python
class Imprimante:
    def imprimer(self, doc):
        # 'doc' = paramètre → dépendance
        # pas stocké dans self
        print(doc.getContenu())

Multiplicité

La multiplicité précise le nombre d'instances qui participent à une relation, de chaque côté.

NotationSignificationExemple
1Exactement 1Un employé a 1 contrat
0..10 ou 1 (optionnel)Une personne a 0 ou 1 permis
*0 ou plusieursUn client a 0 ou N commandes
1..*1 ou plusieursUne équipe a au moins 1 joueur
2..5De 2 à 5Un polygone a 2 à 5 côtés
3Exactement 3Un triangle a 3 sommets

Exemple avec multiplicités

Auteur - nom : String - nationalite : str Livre - titre : String - isbn : String Éditeur - nom : String - pays : String * 1..* écrit * 1 publié par

Exemple Complet — Bibliothèque

Diagramme complet : héritage, association, composition, dépendance et multiplicités.

«abstract» Personne # nom : String # email : String Membre - idMembre : int - dateInscr : Date + emprunter(l:Livre) + retourner(l:Livre) Emprunt - dateEmprunt : Date - dateRetour : Date - estEnRetard : bool + calculerAmende() Bibliothécaire - matricule : String - poste : String + ajouterLivre(l:Livre) + gererStock() Livre - isbn : String - titre : String - disponible : bool Catalogue - nom : String + rechercher(t:str) + listerLivres() 1 0..* 1 1..3 1..* 1 «use» LÉGENDE : Héritage Association Composition ◆ Dépendance

UML → Python

Traduction directe de chaque notation UML en code Python.

Classe abstraite avec membre statique

«abstract» Forme # couleur : String = "rouge" + nbFormes : int = 0 + aire() : float + getCouleur() : String
Python
from abc import ABC, abstractmethod

class Forme(ABC):             # abstraite
    nb_formes = 0              # statique

    def __init__(self, couleur="rouge"):
        self._couleur = couleur  # protégé #
        Forme.nb_formes += 1

    @abstractmethod
    def aire(self) -> float: ... # abstraite

    def getCouleur(self):       # concrète
        return self._couleur

Composition ◆

Maison Pièce 1..n
Python
class Maison:
    def __init__(self, n):
        # pièces créées DANS __init__
        self.pieces = [Piece() for _ in range(n)]

Agrégation ◇

Equipe Joueur *
Python
class Equipe:
    def __init__(self):
        self.joueurs = []  # liste vide

    def ajouter(self, j):
        # joueur externe injecté
        self.joueurs.append(j)

Aide-mémoire

👁 Visibilité

+public
-privé
#protégé
~package

📐 Notations

italiqueabstrait
soulignéstatique
«stéréotype»guillemets
PascalCasenoms classes
camelCaseattributs/méth.

🔗 Relations

——▶Association
◇——Agrégation
◆——Composition
——▷Héritage
- -▷Réalisation
- -▶Dépendance

🔢 Multiplicités

1exactement 1
0..10 ou 1
*0 ou plusieurs
1..*1 ou plusieurs
n..mde n à m
🎯 Conseil clé : lisez toujours les relations dans les deux sens pour vérifier leur cohérence. « Une Maison est composée de Pièces » ✓ et « Une Pièce fait partie d'une Maison » ✓.