UML - Les quatre types de relations

Olivier Capuozzo

04-avril-2003

Résumé

UML définit quatre type de relations entre éléments. Le développeur doit parfaitement en maîtriser la sémantique et la notation.

Ce document présente l'essentiel à retenir en la matière.


Table des matières

Relations
1) Relation structurelle (ou association)
2) Relation de spécialisation/généralisation
3) Relation de réalisation
4) Relation de dépendance
En conclusion
Exercice
Références
Solution de l'exercice

Relations

UML définit quatre types de relation : relation structurelle, de spécialisation/généralisation, de réalisation et de dépendance.

1) Relation structurelle (ou association)

1) Relation structurelle (ou association)

Une relation structurelle décrit un ensemble de liens. Un lien est une connexion entre objets.

Exemple : Un contrat concerne un client.

      class Contrat {
        Client bénéficiaire;
        ...
      }
    

Le bénéficiaire est une des caractéristiques d'un contrat ; la relation est structurelle.

Cette relation est représentée par un trait plein, pouvant être orienté. La multiplicité est notée du côté du rôle cible de l'association. Elle spécifie le nombre d'instances pouvant être associées (liées) avec une seule instance source de la relation. Dans la phrase un contrat concerne un client, contrat est la source et client est la destination.

Une multiplicité est exprimée soit par un couple de valeur N..M soit par une seule valeur lorsque N est M sont égaux.

Tableau 1. Multiplicité

ExempleInterprétation
1..1 ou 1Un et un seul
0..1zéro ou un seul
0..* ou *zéro à plusieurs
3..4trois à quatre
4quatre et seulement quatre

Note : un lien relie une classe soit à elle-même (relation réflexive) soit à une autre classe. Au delà de 2 classes participant à la relation, les traits partent de chacun des rôles et convergent vers un même losange (référence à une classe association, concept non étudié ici).

2) Relation de spécialisation/généralisation

Relation d'héritage, dans laquelle les objets de l'élément spécialisé (classe enfant) peuvent remplacer les objets de l'élément général (classe parent).

Exemple : Un client professionnel est une sorte de client.

      class ClientProfessionnel extends Client {
     
        ...
      }
    

Notation UML : Un trait plein, orienté de la classe spécialisée (enfant) vers son modèle (parent) et se terminant par une flèche fermée.

Attention : Ceci n'est vrai que si un client professionnel se comporte comme un client.

3) Relation de réalisation

Relation dans laquelle une interface définit un contrat garanti par une classe d'implémentation.

Exemple : Le formulaire SaisirClient est un écouteur d'événements.

      class SaisirClient extends JFrame implements ActionListener {
     
        ...
        public void actionPerformed(ActionEvent e) {
           // faire quelque chose
        }
      }
    

La fenêtre SaisirClient réalise le contrat définit par l'interface ActionListener.

Notation UML : Un trait discontinu partant de la classe d'implémentation et allant vers l'interface, se terminant par une pointe de flèche fermée, la même utilisée par la spécialisation/généralisation.

Notation simplifée : Une interface peut être représentée par un petit cercle avec le nom de l'interface placé juste en dessous. Le cercle peut être attaché à une ou plusieurs classes d'implémentation.

4) Relation de dépendance

Relation entre éléments du modèle ne nécessitant pas forcément un lien entre objets. Lorsque cette relation est réalisée par des liens entre objets, ces derniers sont limités dans le temps, contrairement à d'autres relations plus structurelles (cas d'une association - voir au-dessus).

Un élément A dépend d'un élément B, lorsque A utilise des services de B.

De ce fait, tout changement dans B peut avoir des répercussions sur A.

Exemple : Un contrat dispose d'un service d'impression (méthode impression), qui utilise une méthode (print), dont la spécification est déclarée par l'interface Printer.

      class Contrat {
     
        ...
        public void impression() {
           Printer imprimante = PrinterFactory.getInstance();
           ...
           imprimante.print(client.getName());
          ...
        }
      }
    

On remarquera que le lien entre un objet "contrat" et une "imprimante" est momentané, il ne dure que le temps d'exécution de la méthode impression. En d'autres termes, l'imprimante n'a pas lieu d'être un attribut de la classe Contrat, et de ce fait, ce n'est pas une association, mais une simple dépendance.

Notation UML : Un trait discontinu partant de la classe dépendante et pointant vers la classe proposant les services sollicités, se terminant par une pointe de flèche ouverte (c'est ce qui la distingue de la relation de réalisation).

En conclusion

Doit-on toujours représenter toutes les relations existantes entre les éléments présents dans un diagramme ?

Pour répondre à cette question, intéressons nous à la notion de diagramme bien structuré.

Un diagramme n'est pas forcément une représentation exhaustive d'un modèle. Un diagramme peut cacher des parties du modèle si cela sert la communication.

Nous reprenons ici la définition des "devoirs" d'un diagramme bien structuré, selon le "guide de l'utilisateur UML" [GUML] :

Un diagramme bien structuré doit :

  • Être centré sur la communication d'un aspect d'une vue du système.

  • Ne contenir que les éléments essentiels à la compréhension de cet aspect.

  • Fournir les détails cohérents avec son niveau d'abstraction (ne montrer que les décorations essentielles à sa compréhension).

  • Ne pas être trop minimaliste afin de ne pas désinformer le lecteur sur une sémantique importante.

Enfin, Martin Fowler [FOWLER] définit le principe de modélisation suivant :

  • Les modèles ne sont pas justes ou faux; ils sont seulement plus ou moins utiles.

Exercice

Vous concevrez un diagramme de classes UML mettant en avant les relations significatives entre classes décrites par l'extrait de code java ci-dessous.

Figure 1. Exemple de représentation d'une classe avec UML

Exemple de représentation d'une classe avec UML

Extrait du code source :

public interface Observer {
  public void update(Observable o);
}

public class Observable {
  Collection observateurs;
  public void notify() {
    Iterator it = this.iterator();
    while (it.hasNext()) {
      ((Observer) it.next()).update(this);
    }
  }
  public void addObserver(Observer o) { observateurs.add(o); }
    ...
  }

public class Bilan extends Observable {
  void setChange() { notify(); }
  ...
}

public class UIGraphe implements Observer { 
  public void update(Observable o) {
    Bilan unbilan = (Bilan) o;
    double compteResultat = unbilan.getCompteResultat();
    ...
  }
 ...
}

Références

  • [GUML] : "Guide de l'utilisateur UML", de Drady Booch, James Rumbaugh et Ivar Jacobson, ed. Eyrolles - 2000

  • [FOWLER] : "Analysis Patterns, Reusable Object Models", de Martin Fowler, ed. Addison Wesley - 2001

  • [FOWLER2] : "UML", de Martin Fowler, coll. "Le tout en poche", ed. CampusPress - 2001

Solution de l'exercice

Figure 2. Illustration des 4 relations de base d'UML

Diagramme réalisé avec Umbrello UML Modeler

Illustration des 4 relations de base d'UML