Garden of KnowledgeApplied Sciences › Computer Science › Software › Architecture Logicielle
April 7, 2026

UML — Unified Modeling Language

UML (Unified Modeling Language) est un langage de modélisation standardisé (OMG, 1997) permettant de représenter graphiquement la structure et le comportement d’un système logiciel.

Types de diagrammes UML§

UML 2.5 propose 14 types de diagrammes regroupés en deux catégories :

CatégorieDiagrammes
StructureClasse, Objet, Composant, Déploiement, Package, Profil, Structure composite
ComportementCas d’utilisation, Activité, Machine à états, Séquence, Communication, Interaction, Temps

En pratique, les plus utilisés sont : Classe, Cas d’utilisation, Séquence, et Activité.

Diagramme de classes§

Le diagramme de classes est le plus fondamental en UML. Il représente la structure statique d’un système : les classes, leurs attributs, méthodes et relations.

Notation d’une classe§

┌─────────────────────────┐
│       NomClasse         │  ← Compartiment nom
├─────────────────────────┤
│ - attributPrivé: Type   │  ← Compartiment attributs
│ # attributProtégé: Type │
│ + attributPublic: Type  │
│ ∼ attributPackage: Type │
├─────────────────────────┤
│ + methodePublique(): void│  ← Compartiment méthodes
│ - methodePrivée(): Type  │
│ {abstract} maMethode()  │
└─────────────────────────┘

Modificateurs d’accès :

Modificateurs de propriété :

Exemple en Java§

// Classe Java → diagramme de classes UML

public abstract class Forme {
    private String couleur;             // - couleur: String
    protected static int compteur = 0;  // # {static} compteur: int

    public Forme(String couleur) {
        this.couleur = couleur;
    }

    public abstract double calculerAire();    // {abstract} + calculerAire(): double
    public String getCouleur() { return couleur; }  // + getCouleur(): String
}

public class Cercle extends Forme {
    private double rayon;              // - rayon: double

    public Cercle(String couleur, double rayon) {
        super(couleur);
        this.rayon = rayon;
    }

    @Override
    public double calculerAire() {     // + calculerAire(): double
        return Math.PI * rayon * rayon;
    }
}

Relations entre classes§

Héritage (Generalization)§

Flèche pleine avec tête triangulaire creuse. “est-un” (is-a).

Forme


Cercle
public class Cercle extends Forme { ... }

Implémentation d’interface (Realization)§

Flèche pointillée avec tête triangulaire creuse.

<<interface>>
   Dessinable
    △ (pointillé)

  Cercle
public class Cercle implements Dessinable { ... }

Association§

Ligne simple. “a une relation avec”. Peut avoir une multiplicité.

Client ────────── Commande
        1    0..*
NotationSignification
1Exactement 1
0..10 ou 1 (optionnel)
* ou 0..*0 à plusieurs
1..*1 à plusieurs
2..5De 2 à 5

Agrégation§

Losange creux côté “tout”. Relation “a” — le tout peut exister sans la partie.

Equipe ◇──────── Joueur
  1        0..*

La Equipe contient des Joueurs, mais un Joueur peut exister sans Equipe.

Composition§

Losange plein côté “tout”. Relation forte — la partie ne peut exister sans le tout.

Maison ◆──────── Chambre
  1         1..*

Si Maison est détruite, Chambre est également détruite.

public class Maison {
    private List<Chambre> chambres = new ArrayList<>();  // Composition
}

Dépendance§

Flèche pointillée. Relation faible et temporaire (utilise dans une méthode).

Commande - - - - → Facture
public class Commande {
    public Facture genererFacture() {  // Commande dépend de Facture
        return new Facture(this);
    }
}

Diagramme de classes complet — exemple e-commerce§

┌─────────────┐         ┌──────────────┐
│   Client    │ 1   0..* │  Commande   │
│─────────────│──────────│──────────────│
│-nom: String │         │-date: Date   │
│-email: String│        │-statut: Enum │
│─────────────│         │──────────────│
│+passer()   │         │+calculerTotal│
└─────────────┘         └──────┬───────┘
                               │ 1

                         1..*  │
                  ┌────────────┴──────┐
                  │  LigneCommande    │
                  │───────────────────│
                  │-quantite: int     │
                  │-prixUnitaire: dec │
                  └────────────┬──────┘
                         *     │
                               │ 1
                  ┌────────────┴──────┐
                  │    Produit        │
                  │───────────────────│
                  │-nom: String       │
                  │-prix: Decimal     │
                  │-stock: int        │
                  └───────────────────┘

Diagramme de séquence§

Représente les interactions entre objets dans le temps. Les participants sont des colonnes, le temps s’écoule vers le bas.

Client      :Contrôleur    :Service      :Dépôt
  │               │              │           │
  │─passer()─────►│              │           │
  │               │─valider()───►│           │
  │               │              │─trouver()►│
  │               │              │◄──client──│
  │               │◄─client──────│           │
  │               │─sauvegarder()►           │
  │               │              │─save()───►│
  │               │              │◄──ok──────│
  │◄──commande────│              │           │
  │               │              │           │

Éléments :

Diagramme de cas d’utilisation§

Représente les fonctionnalités d’un système du point de vue de l’utilisateur.

              ┌─────────────────────────────┐
              │         Système e-commerce   │
              │                             │
Client ──────►│  (Parcourir catalogue)      │
              │  (Ajouter au panier)        │
              │  (Passer commande)          │──────► Admin
              │  (Suivre livraison)         │  │
              │                             │  └── (Gérer produits)
              └─────────────────────────────┘

Acteur : représenté par un bonhomme. Rôle externe qui interagit avec le système.

Relations :

(Passer commande) ─ <<include>> ─► (S'authentifier)
(Passer commande) ◄ <<extend>> ── (Utiliser bon de réduction)

Diagramme d’activité§

Représente un flux de travail ou un algorithme. Similaire à un organigramme.

    ●  (Début)


 [Saisir données]


  ◇ Données valides ?
  │ Oui               │ Non
  ▼                   ▼
 [Traiter]         [Afficher erreur]
  │                   │
  └─────────┬─────────┘

         [Fin]

           ◉  (Fin)

Éléments :

Polymorphisme en UML et Java§

Polymorphisme par héritage (override)§

// Classe mère abstraite
public abstract class Animal {
    private String nom;

    public Animal(String nom) { this.nom = nom; }
    public String getNom() { return nom; }

    public abstract String parler();  // Méthode abstraite
}

// Sous-classes — chacune redéfinit parler()
public class Chien extends Animal {
    public Chien(String nom) { super(nom); }

    @Override
    public String parler() { return "Woof !"; }
}

public class Chat extends Animal {
    public Chat(String nom) { super(nom); }

    @Override
    public String parler() { return "Miaou !"; }
}

// Polymorphisme : référence de type Animal → comportement du type réel
List<Animal> animaux = List.of(new Chien("Rex"), new Chat("Félix"));
for (Animal a : animaux) {
    System.out.println(a.getNom() + " dit : " + a.parler());
    // Rex dit : Woof !
    // Félix dit : Miaou !
}

Polymorphisme par interface§

public interface Payable {
    double calculerMontant();
    default String formatMontant() {
        return String.format("%.2f €", calculerMontant());
    }
}

public class Salaire implements Payable {
    private double montantMensuel;
    public double calculerMontant() { return montantMensuel; }
}

public class Facture implements Payable {
    private double[] lignes;
    public double calculerMontant() {
        return Arrays.stream(lignes).sum();
    }
}

// Un même code traite Salaire et Facture via l'interface
void traiterPaiement(Payable p) {
    System.out.println("À payer : " + p.formatMontant());
}

Surcharge (overloading) — polymorphisme statique§

public class Calculatrice {
    public int additionner(int a, int b) { return a + b; }
    public double additionner(double a, double b) { return a + b; }
    public int additionner(int a, int b, int c) { return a + b + c; }
    // Résolution à la compilation selon le type des arguments
}

Encapsulation§

L’encapsulation cache l’implémentation interne et expose uniquement une interface publique. Elle protège l’intégrité de l’objet et permet de changer l’implémentation sans affecter les clients.

public class CompteBancaire {
    private double solde;         // Attribut privé — non accessible de l'extérieur
    private List<String> historique = new ArrayList<>();

    public CompteBancaire(double soldeInitial) {
        if (soldeInitial < 0) throw new IllegalArgumentException("Solde initial négatif");
        this.solde = soldeInitial;
    }

    // Getter — accès en lecture
    public double getSolde() { return solde; }

    // Pas de setter pour solde — uniquement via deposer/retirer (invariants garantis)

    public void deposer(double montant) {
        if (montant <= 0) throw new IllegalArgumentException("Montant invalide");
        solde += montant;
        historique.add("Dépôt : +" + montant);
    }

    public void retirer(double montant) {
        if (montant <= 0) throw new IllegalArgumentException("Montant invalide");
        if (montant > solde) throw new IllegalStateException("Solde insuffisant");
        solde -= montant;
        historique.add("Retrait : -" + montant);
    }

    // Copie défensive pour éviter que le client modifie l'historique interne
    public List<String> getHistorique() {
        return Collections.unmodifiableList(historique);
    }
}

Choisir le bon diagramme§

QuestionDiagramme
Quelle est la structure des données et des classes ?Classe
Comment les objets interagissent-ils dans un scénario ?Séquence
Quelles sont les fonctionnalités du système ?Cas d’utilisation
Comment se déroule un processus ou algorithme ?Activité
Dans quels états peut se trouver un objet ?Machine à états
Comment sont déployés les composants ?Déploiement
—The Gardener