Le livre du Dr Yan Hong "JAVA and Patterns" commence par une description du modèle Mediator :
Le modèle médiateur est le modèle de comportement des objets. Le modèle Mediator résume la manière dont un ensemble d'objets interagissent afin qu'ils n'aient pas besoin de se référencer explicitement les uns les autres. Cela leur permet d'être faiblement couplés. Lorsque les interactions entre certains de ces objets changent, cela n’affecte pas immédiatement les interactions entre d’autres objets. Cela garantit que ces interactions peuvent varier indépendamment les unes des autres.
Pourquoi un médiateur est nécessaire
Comme le montre la figure ci-dessous, ce diagramme schématique contient un grand nombre d'objets. Ces objets peuvent à la fois affecter d'autres objets et être affectés par d'autres objets, ils sont donc souvent appelés objets Collègue. Ces collaborateurs façonnent le comportement du système grâce à leurs interactions les uns avec les autres. Comme le montre la figure, presque tous les objets doivent interagir avec d’autres objets, et cette interaction se manifeste par un couplage direct entre un objet et un autre objet. Il s'agit d'un système surcouplé.
En introduisant l'objet médiateur (Mediator), la structure de réseau du système peut être transformée en une structure en étoile centrée sur le médiateur, comme le montre la figure ci-dessous. Dans cette structure en étoile, un objet collègue n’interagit plus avec un autre objet via une connexion directe, mais avec un autre objet via un objet médiateur ; L'existence de l'objet médiateur garantit la stabilité de la structure de l'objet, c'est-à-dire que la structure du système n'entraînera pas beaucoup de travaux de modification en raison de l'introduction de nouveaux objets.
Une bonne conception orientée objet peut accroître la collaboration et réduire le couplage entre les objets. Une conception bien pensée décompose un système en un groupe d'objets collaborateurs coopérants, puis confère à chaque objet collaborateur des responsabilités uniques et configure de manière appropriée les relations de collaboration entre eux afin qu'ils puissent travailler ensemble.
S'il n'y a pas de carte mère
Comme nous le savons tous, l’interaction entre les différents accessoires de l’ordinateur s’effectue principalement via la carte mère. S’il n’y a pas de carte mère dans l’ordinateur, alors les différents accessoires doivent interagir de manière autonome entre eux pour se transmettre des données. Et comme les interfaces de chaque accessoire sont différentes, lors de l'interaction les unes avec les autres, l'interface de données doit être convertie pour correspondre.
Heureusement, avec la carte mère, l'interaction des divers accessoires est entièrement complétée via la carte mère. Chaque accessoire n'a besoin que d'interagir avec la carte mère, et la carte mère sait gérer tous les accessoires, ce qui rend les choses beaucoup plus simples.
La structure du modèle médiateur
Un diagramme de classes schématique pour le modèle Mediator est présenté ci-dessous :
Le mode Médiateur inclut les rôles suivants :
● Rôle de médiateur abstrait (Mediator) : Définissez l'interface de l'objet collègue vers l'objet médiateur, dans laquelle la méthode principale est une (ou plusieurs) méthodes événementielles.
● Rôle Concrete Mediator (ConcreteMediator) : implémente la méthode événementielle déclarée par le médiateur abstrait. Le médiateur spécifique connaît toutes les classes spécifiques de collègues et est chargé de coordonner spécifiquement l'interaction entre chaque objet collègue.
● Rôle de la classe collègue abstraite (Colleague) : définit l'interface du médiateur vers l'objet collègue. Les objets collègues ne connaissent que le médiateur et non les autres objets collégiaux.
● Rôle ConcreteColleague : toutes les classes de collègues concrètes héritent de la classe de collègues abstraite. Pour mettre en œuvre votre propre entreprise, lorsque vous avez besoin de communiquer avec d'autres collègues, communiquez avec le médiateur qui la détient. Le médiateur sera chargé d'interagir avec d'autres collègues.
code source
Le code de copie de la classe médiateur abstrait est le suivant :
Médiateur d'interface publique {
/**
* L'objet collègue informe la méthode médiateur lorsqu'il change.
* Laissez le médiateur être responsable des interactions correspondantes avec d'autres objets collègues
*/
le vide public a été modifié (collègue c);
}
cours de médiateur concret
Copiez le code comme suit :
classe publique ConcreteMediator implémente Mediator {
// Détenir et maintenir le collègue A
privé ConcreteColleagueA collègueA ;
// Détenir et entretenir le collègue B
collègue ConcreteColleagueB privéB ;
public void setColleagueA(ConcreteColleagueA collègueA) {
this.colleagueA = collègueA;
}
public void setColleagueB (ConcreteColleagueB collègueB) {
this.colleagueB = collègueB;
}
@Outrepasser
public void modifié (collègue c) {
/**
* Une certaine classe de collègues a changé, nécessitant généralement une interaction avec d'autres collègues
* Coordonner spécifiquement les objets collègues correspondants pour obtenir un comportement collaboratif
*/
}
}
classe de collègue abstraite
Copiez le code comme suit :
Collègue de classe abstraite publique {
//Maintient un objet médiateur
Médiateur médiateur privé;
/**
*Constructeur
*/
Collègue public(Médiateur médiateur){
this.mediator = médiateur ;
}
/**
* Récupérez l'objet médiateur correspondant à la classe de collègue actuelle
*/
Médiateur public getMediator() {
médiateur de retour ;
}
}
Le code spécifique pour copier la même classe est le suivant :
classe publique ConcreteColleagueA étend Colleague {
public ConcreteColleagueA (Médiateur médiateur) {
super(médiateur);
}
/**
* Indiquer les méthodes pour effectuer certaines opérations
*/
opération publique vide(){
//Notifiez l'objet médiateur lorsque vous devez communiquer avec d'autres collègues
getMediator().changed(this);
}
}
Copiez le code comme suit :
classe publique ConcreteColleagueB étend Colleague {
public ConcreteColleagueB (Médiateur médiateur) {
super(médiateur);
}
/**
* Indiquer les méthodes pour effectuer certaines opérations
*/
opération publique vide(){
//Notifiez l'objet médiateur lorsque vous devez communiquer avec d'autres collègues
getMediator().changed(this);
}
}
Utilisez votre ordinateur pour regarder des films
Dans la vie quotidienne, nous utilisons souvent des ordinateurs pour regarder des films. Après simplification, nous supposons qu’il y aura le processus interactif suivant :
(1) Tout d'abord, le lecteur optique doit lire les données sur le disque optique, puis indiquer à la carte mère que son état a changé.
(2) La carte mère obtient les données du lecteur optique et les transmet au processeur pour analyse et traitement.
(3) Une fois le traitement terminé, le processeur divise les données en données vidéo et données audio et informe la carte mère qu'il a terminé le traitement.
(4) La carte mère obtient les données traitées par le processeur et transmet les données respectivement à la carte graphique et à la carte son pour afficher la vidéo et émettre des sons.
Pour implémenter l'exemple en utilisant le modèle médiateur, il est nécessaire de faire la distinction entre les objets collègues et les objets médiateurs. Évidemment, la carte mère est le médiateur et les accessoires tels que les lecteurs optiques, les cartes son, les processeurs et les cartes graphiques sont tous des collègues.
code source
Le code de copie de la classe collègue abstraite est le suivant :
Collègue de classe abstraite publique {
//Maintient un objet médiateur
Médiateur médiateur privé;
/**
*Constructeur
*/
Collègue public(Médiateur médiateur){
this.mediator = médiateur ;
}
/**
* Récupérez l'objet médiateur correspondant à la classe de collègue actuelle
*/
Médiateur public getMediator() {
médiateur de retour ;
}
}
Classe de collègue - le code de copie du lecteur optique est le suivant :
CDDriver de classe publique étend Colleague{
//Données lues depuis le lecteur optique
données de chaîne privées = "" ;
/**
*Constructeur
*/
public CDDriver (Médiateur médiateur) {
super(médiateur);
}
/**
* Obtenez les données lues sur le disque
*/
chaîne publique getData() {
renvoyer des données ;
}
/**
* Lire le CD
*/
public void readCD(){
//Avant la virgule se trouvent les données affichées dans la vidéo, et après la virgule se trouvent le son
this.data = "One Piece, je suis déterminé à être le roi des pirates" ;
//Avertissez la carte mère que son statut a changé
getMediator().changed(this);
}
}
Classe de collègue——CPU
Copiez le code comme suit :
Le processeur de classe publique étend Colleague {
//Données vidéo décomposées
chaîne privée videoData = "" ;
//Données sonores décomposées
chaîne privée soundData = "" ;
/**
*Constructeur
*/
CPU public (médiateur médiateur) {
super(médiateur);
}
/**
* Obtenez des données vidéo décomposées
*/
chaîne publique getVideoData() {
renvoyer des données vidéo ;
}
/**
* Obtenez les données sonores décomposées
*/
chaîne publique getSoundData() {
renvoyer soundData ;
}
/**
* Traiter les données et diviser les données en données audio et vidéo
*/
public void exécuterData(String données){
// Décomposez les données. Le recto est constitué de données vidéo et le verso est constitué de données audio.
Tableau String[] = data.split(",");
this.videoData = tableau[0];
this.soundData = tableau[1];
//Avertissez la carte mère que le CPU a terminé le travail
getMediator().changed(this);
}
}
Classe de collègue - le code de copie du code de la carte graphique est le suivant :
La carte vidéo de classe publique étend le collègue {
/**
*Constructeur
*/
Carte vidéo publique (médiateur médiateur) {
super(médiateur);
}
/**
* Afficher les données vidéo
*/
public void showData (chaîne de données) {
System.out.println("Vous regardez : " + données);
}
}
Classe de collègue - le code de copie du code de la carte son est le suivant :
La SoundCard de classe publique étend Colleague {
/**
*Constructeur
*/
Public SoundCard (Médiateur médiateur) {
super(médiateur);
}
/**
* Créez des sons basés sur des données audio
*/
public void soundData (chaîne de données) {
System.out.println("Voix off : " + données);
}
}
Le code de copie de la classe médiateur abstrait est le suivant :
Médiateur d'interface publique {
/**
* L'objet collègue informe la méthode médiateur lorsqu'il change.
* Laissez le médiateur être responsable des interactions correspondantes avec d'autres objets collègues
*/
le vide public a été modifié (collègue c);
}
Le code de copie spécifique de la classe médiateur est le suivant :
la classe publique MainBoard implémente Mediator {
//Besoin de connaître la classe du collègue pour interagir avec la classe du lecteur optique
CDDriver privé cdDriver = null ;
//Besoin de connaître la classe collègue pour interagir avec la classe CPU
CPU privé CPU = null ;
//Besoin de connaître la classe de collègues avec qui interagir - la classe de la carte graphique
VideoCard privée videoCard = null ;
//Besoin de connaître la classe de collègues avec qui interagir - la classe de carte son
carte son privée soundCard = null ;
public void setCdDriver(CDDriver cdDriver) {
this.cdDriver = cdDriver ;
}
public void setCpu (CPU cpu) {
this.cpu = processeur ;
}
public void setVideoCard (VideoCard videoCard) {
this.videoCard = videoCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
@Outrepasser
public void modifié (collègue c) {
si (c instance de CDDriver) {
//Indique que le lecteur optique a lu des données
this.opeCDDriverReadData((CDDriver)c);
}sinon si(c instance de CPU){
this.opeCPU((CPU)c);
}
}
/**
* Gérer l'interaction avec d'autres objets après que le lecteur optique ait lu les données
*/
privé vide opeCDDriverReadData (CDDriver cd){
//Récupère d'abord les données lues par le lecteur optique
Données de chaîne = cd.getData();
//Transférer ces données vers la CPU pour traitement
cpu.executeData(données);
}
/**
* Gérer l'interaction entre le CPU et d'autres objets après le traitement des données
*/
opeCPU privé vide (CPU cpu){
//Récupère d'abord les données traitées par le CPU
Chaîne videoData = cpu.getVideoData();
Chaîne soundData = cpu.getSoundData();
//Transférer ces données vers la carte graphique et la carte son pour les afficher
videoCard.showData(videoData);
soundCard.soundData(soundData);
}
}
Le code de copie de la classe client est le suivant :
Client de classe publique {
public static void main (String[] arguments) {
//Créer un médiateur - carte mère
Médiateur MainBoard = new MainBoard();
//Créer une classe de collègue
CDDriver cd = nouveau CDDriver (médiateur) ;
CPU cpu = nouveau CPU (médiateur) ;
VideoCard vc = nouvelle VideoCard (médiateur);
SoundCard sc = nouvelle SoundCard (médiateur) ;
//Faites connaître au médiateur tous les collègues
médiateur.setCdDriver(cd);
médiateur.setCpu(cpu);
mediator.setVideoCard(vc);
médiateur.setSoundCard(sc);
// Commencez à regarder le film, insérez le disque dans le lecteur optique et le lecteur optique commence à lire le disque
cd.readCD();
}
}
Les résultats en cours d'exécution sont les suivants :
Avantages du modèle médiateur
● accouplement lâche
Le modèle médiateur encapsule les interactions entre plusieurs objets collègues dans l'objet médiateur, couplant ainsi vaguement les objets collègues et obtenant fondamentalement des dépendances complémentaires. De cette manière, les objets des collègues peuvent être modifiés et réutilisés indépendamment, au lieu de « se déplacer d'un endroit et d'affecter l'ensemble du corps » comme auparavant.
● Contrôle centralisé des interactions
Les interactions de plusieurs objets collègues sont encapsulées dans l'objet médiateur pour une gestion centralisée, de sorte que lorsque ces comportements interactifs changent, il vous suffit de modifier l'objet médiateur. Bien sûr, s'il s'agit d'un système déjà terminé, développez l'objet médiateur, et chaque classe de collègue n'a pas besoin d'être modifiée.
● Plusieurs-à-plusieurs deviennent un-à-plusieurs
Lorsque le modèle médiateur n'est pas utilisé, la relation entre les objets collègues est généralement plusieurs-à-plusieurs. Une fois l'objet médiateur introduit, la relation entre l'objet médiateur et l'objet collègue devient généralement un-à-plusieurs bidirectionnel. ce qui rend la relation entre les objets plus facile à comprendre et à mettre en œuvre.
Inconvénients du modèle médiateur
Un inconvénient potentiel du modèle médiateur est la centralisation excessive. Si l'interaction des objets collègues est très vaste et complexe, lorsque toutes ces complexités sont concentrées sur le médiateur, l'objet médiateur deviendra très complexe et difficile à gérer et à maintenir.