Le patron de conception Médiateur (Mediator) est un pattern comportemental dont l'objectif principal est de réduire la complexité des communications entre plusieurs objets. Au lieu que les objets interagissent directement entre eux — ce qui crée un couplage fort et un réseau de dépendances difficile à maintenir — ils communiquent par l'intermédiaire d'un objet central : le médiateur.
Ce concept est comparable à une tour de contrôle dans un aéroport ou à une agence immobilière qui centralise les offres et les demandes sans que les acheteurs et les vendeurs n'aient besoin de se connaître initialement.
Structure du Médiateur
Dans l'exemple suivant, nous allons simuler un système d'échange commercial où des intervenants passent par une plateforme centrale pour négocier des transactions.
1. L'interface du Médiateur
Il est préférable de définir une interface pour le médiateur afin de maintenir une flexibilité dans l'évolution du système.
public interface IPlateforme {
void enregistrerMembre(Intervenant membre);
void publierOffre(Intervenant emetteur, double prix);
}
2. Implémentation concrète (Singleton)
Ici, la plateforme agit comme l'unique point de contact pour tous les participants.
import java.util.ArrayList;
import java.util.List;
public class CentreEchange implements IPlateforme {
private List<Intervenant> catalogueMembres = new ArrayList<>();
private static final CentreEchange instance = new CentreEchange();
private CentreEchange() {}
public static CentreEchange getInstance() {
return instance;
}
@Override
public void enregistrerMembre(Intervenant membre) {
catalogueMembres.add(membre);
}
@Override
public void publierOffre(Intervenant emetteur, double prix) {
System.out.println("[Système] Nouvelle offre détectée : " + prix + " €");
for (Intervenant participant : catalogueMembres) {
// Le médiateur filtre l'émetteur et vérifie les conditions d'achat
if (participant != emetteur && participant.getBudgetMax() >= prix) {
participant.notifierValidation();
}
}
}
}
3. La classe abstraite des Participants
Chaque intervenant possède une référence vers le médiateur pour envoyer ses informations.
public abstract class Intervenant {
protected IPlateforme mediateur;
protected String nom;
protected double budgetMax;
public Intervenant(String nom, double budgetMax) {
this.nom = nom;
this.budgetMax = budgetMax;
this.mediateur = CentreEchange.getInstance();
}
public double getBudgetMax() {
return budgetMax;
}
public abstract void emettreOffre(double prix);
public abstract void notifierValidation();
}
4. Implémentation des acteurs concrets
Les acteurs ne connaissent que le médiateur et leur propre logique interne.
public class Investisseur extends Intervenant {
public Investisseur(String nom, double budget) {
super(nom, budget);
}
@Override
public void emettreOffre(double prix) {
System.out.println(this.nom + " propose une vente à " + prix + " €");
mediateur.publierOffre(this, prix);
}
@Override
public void notifierValidation() {
System.out.println(this.nom + " : J'accepte cette transaction !");
}
}
Exemple d'exécution
L'exemple suivant montre comment le médiateur orchestre la communication entre deux investisseurs sans qu'ils ne s'appellent directement.
public class DemonstrationMediateur {
public static void main(String[] args) {
IPlateforme bourse = CentreEchange.getInstance();
Intervenant investisseurA = new Investisseur("Client_Alpha", 1500.0);
Intervenant investisseurB = new Investisseur("Client_Beta", 3000.0);
bourse.enregistrerMembre(investisseurA);
bourse.enregistrerMembre(investisseurB);
// L'investisseur B publie une offre que A pourrait potentiellement accepter
investisseurB.emettreOffre(1200.0);
}
}
Le point crucial de ce patron est que les objets Investisseur sont totalement indépendants les uns des autres. Si un nouvel investisseur rejoint la plateforme, seul le médiateur doit être au courant, évitant ainsi une explosion du nombre de connexions entre les classes du système.