Mediator
(Médiateur)

But : Définir un objet qui encapsule comment un ensemble d'objets interagit.
Les objets qui interagissent n'ont plus besoin d'échanger directement avec les autres objets, ce qui permet de faire varier les interaction indépendamment des objets.

Assez proche de Observer.

Exemples

Tour de contrôle

Mediator - tour de contrôle Les pilotes des avions qui vont atterrir ne communiquent pas entre eux pour savoir comment s'y prendre ;
ils communiquent tous avec la tour de contrôle, qui leur donne en retour des instructions.
L'intelligence permettant de gérer les interactions entre les avions se situe au niveau de la tour.
Les différents avions n'ont pas besoin de se connaître pour pouvoir atterrir, les instructions de la tour suffisent.

Exemple GOF

Autre exemple, dans un dialogue permettant de choisir une police, une action peut avoir des effets sur plusieurs composants graphiques : Différents dialogues peuvent utiliser les mêmes composants graphiques, mais les interactions des composants entre eux seront différentes.
En sous-classant les composants pour gérer les différents types d'interaction, on supprime la possibilité de les réutiliser.
On crée aussi des dépendances fortes entre les composants.
Mediator - exemple Mediator - interactions
On évite ces problèmes en encapsulant les interaction dans un objet, le mediator.

Par exemple, on pourrait avoir un FontDialogDirector pour faire le mediator entre les composants du dialogue.
Le FontDialogDirector connaît les composants, agit comme un hub pour gérer les interactions.

Diagramme de séquence : Mediator - sequence
  1. La liste dit au mediator qu'elle a changé.
  2. Le mediator lui demande sa nouvelle valeur.
  3. Le médiator demande au texte de se rafraîchir.
  4. Le médiator demande à "Weight", puis "Slant", puis "Size" de se rafraîchir (en utilisant les valeurs récupérées en 2).
Mediator - exemple DialogDirector Bonne organistation du code, toutes les interactions sont centralisées dans le mediator :
class Mediator{
    
    public void widgetChanged(Widget w){
        switch(w.getClass()){
        	case Widget1.class : handleWidget1(); break;
        	case Widget2.class : handleWidget2(); break;
        }
    }
    
    private void handleWidget1(){
        // ici toutes les opérations réagissant à une action de l'utilisateur
        // sont réunies en un même endroit
    }
}
Si les fonctions du type de handleWidget1() sont longues et complexes, on peut sous-classer Mediator pour mieux ranger le code.

Autre exemple

Voir ChatDemo.java
Bien identifier la séquence : lorsqu'un utilisateur envoie un message, c'est bien lui qui est à l'initiative du message, mais ne fait que transmettre au ChatMediator, qui a la responsabilité de transmettre le message aux participants concernés.

Structure

Mediator - structure

Remarques

Liens avec d'autres patterns