Dr. Yan Hongs Buch „JAVA and Patterns“ beginnt mit einer Beschreibung des Mediator-Musters:
Das Mediatormuster ist das Verhaltensmuster von Objekten. Das Mediator-Muster fasst die Art und Weise zusammen, wie eine Reihe von Objekten interagieren, sodass sie nicht explizit aufeinander verweisen müssen. Dadurch können sie lose gekoppelt werden. Wenn sich die Interaktionen zwischen einigen dieser Objekte ändern, hat dies keinen unmittelbaren Einfluss auf die Interaktionen zwischen anderen Objekten. Dadurch wird sichergestellt, dass diese Interaktionen unabhängig voneinander variieren können.
Warum ein Mediator benötigt wird
Wie in der folgenden Abbildung dargestellt, gibt es in diesem schematischen Diagramm eine große Anzahl von Objekten. Diese Objekte können sich sowohl auf andere Objekte auswirken als auch von anderen Objekten beeinflusst werden. Daher werden sie häufig als Kollegenobjekte bezeichnet. Diese Mitarbeiter prägen durch ihre Interaktion untereinander das Verhalten des Systems. Wie aus der Abbildung ersichtlich ist, muss fast jedes Objekt mit anderen Objekten interagieren, und diese Interaktion manifestiert sich als direkte Kopplung zwischen einem Objekt und einem anderen Objekt. Es handelt sich um ein überkoppeltes System.
Durch die Einführung des Mediatorobjekts (Mediator) kann die Netzwerkstruktur des Systems in eine auf dem Mediator zentrierte Sternstruktur umgewandelt werden, wie in der folgenden Abbildung dargestellt. In dieser Sternstruktur interagiert ein Kollegenobjekt nicht mehr über eine direkte Verbindung mit einem anderen Objekt, sondern über ein Mittlerobjekt. Die Existenz des Mediatorobjekts stellt die Stabilität der Objektstruktur sicher, das heißt, die Systemstruktur verursacht aufgrund der Einführung neuer Objekte keinen großen Änderungsaufwand.
Ein gutes objektorientiertes Design kann die Zusammenarbeit verbessern und die Kopplung zwischen Objekten verringern. Ein gut durchdachtes Design unterteilt ein System in eine Gruppe kooperierender Mitarbeiterobjekte, weist dann jedem Mitarbeiterobjekt eindeutige Verantwortlichkeiten zu und konfiguriert die kollaborativen Beziehungen zwischen ihnen entsprechend, sodass sie zusammenarbeiten können.
Wenn kein Motherboard vorhanden ist
Wie wir alle wissen, erfolgt die Interaktion zwischen verschiedenen Zubehörteilen im Computer hauptsächlich über das Motherboard. Wenn im Computer kein Motherboard vorhanden ist, müssen die verschiedenen Zubehörteile eigenständig miteinander interagieren, um Daten untereinander zu übertragen. Und da die Schnittstellen jedes Zubehörs unterschiedlich sind, muss bei der Interaktion untereinander die Datenschnittstelle entsprechend konvertiert werden.
Glücklicherweise erfolgt beim Motherboard die Interaktion verschiedener Zubehörteile vollständig über das Motherboard. Jedes Zubehörteil muss nur mit dem Motherboard interagieren, und das Motherboard weiß, wie es mit allen Zubehörteilen umgeht, was es viel einfacher macht.
Die Struktur des Mediatormusters
Ein schematisches Klassendiagramm für das Mediator-Muster ist unten dargestellt:
Der Mediatormodus umfasst die folgenden Rollen:
● Rolle des abstrakten Vermittlers (Mediator): Definieren Sie die Schnittstelle vom Kollegenobjekt zum Vermittlerobjekt, in dem die Hauptmethode eine (oder mehrere) Ereignismethoden ist.
● Rolle des konkreten Vermittlers (ConcreteMediator): Implementiert die vom abstrakten Vermittler deklarierte Ereignismethode. Der spezifische Mediator kennt alle spezifischen Kollegenklassen und ist für die spezifische Koordinierung der Interaktion zwischen den einzelnen Kollegenobjekten verantwortlich.
● Abstrakte Kollegenklasse (Kollege) Rolle: Definiert die Schnittstelle vom Vermittler zum Kollegenobjekt. Kollegenobjekte kennen nur den Mediator und nicht die anderen kollegialen Objekte.
● ConcreteColleague-Rolle: Alle konkreten Kollegenklassen erben von der abstrakten Kollegenklasse. Um Ihr eigenes Geschäft umzusetzen, kommunizieren Sie mit dem Mediator, der es führt, wenn Sie mit anderen Kollegen kommunizieren müssen. Der Mediator ist für die Interaktion mit anderen Kollegen verantwortlich.
Quellcode
Der Kopiercode der abstrakten Mediatorklasse lautet wie folgt:
öffentliche Schnittstelle Mediator {
/**
* Das Kollegenobjekt benachrichtigt die Mediatormethode, wenn es sich ändert.
* Lassen Sie den Mediator für die entsprechenden Interaktionen mit anderen Kollegenobjekten verantwortlich sein
*/
öffentliche Leere geändert (Kollege c);
}
konkrete Mediatorenklasse
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse ConcreteMediator implementiert Mediator {
//Kollege A halten und aufrechterhalten
privat ConcreteColleagueA KollegeA;
//Kollege B halten und aufrechterhalten
privat ConcreteColleagueB KollegeB;
public void setColleagueA(ConcreteColleagueAKollegeA) {
this.colleagueA = KollegeA;
}
public void setColleagueB(ConcreteColleagueB KollegeB) {
this.colleagueB = KollegeB;
}
@Override
öffentliche Leere geändert(Kollege c) {
/**
* Eine bestimmte Kollegenklasse hat sich geändert, was normalerweise eine Interaktion mit anderen Kollegen erfordert
* Koordinieren Sie gezielt die entsprechenden Kollegenobjekte, um kollaboratives Verhalten zu erreichen
*/
}
}
abstrakte Kollegenklasse
Kopieren Sie den Codecode wie folgt:
öffentliche abstrakte Klasse Kollege {
//Halten Sie ein Mediatorobjekt
privater Mediator; Mediator;
/**
*Konstrukteur
*/
öffentlicher Kollege (Mediator Mediator){
this.mediator = Vermittler;
}
/**
* Holen Sie sich das Mediatorobjekt, das der aktuellen Kollegenklasse entspricht
*/
öffentlicher Mediator getMediator() {
Rückkehrvermittler;
}
}
Der spezifische Code zum Kopieren derselben Klasse lautet wie folgt:
öffentliche Klasse ConcreteColleagueA erweitert Colleague {
public ConcreteColleagueA(Mediator mediator) {
Super(Vermittler);
}
/**
* Geben Sie Methoden zum Ausführen bestimmter Vorgänge an
*/
public void operation(){
// Benachrichtigen Sie das Mediatorobjekt, wenn Sie mit anderen Kollegen kommunizieren müssen
getMediator().changed(this);
}
}
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse ConcreteColleagueB erweitert Colleague {
public ConcreteColleagueB(Mediator mediator) {
Super(Vermittler);
}
/**
* Geben Sie Methoden zum Ausführen bestimmter Vorgänge an
*/
public void operation(){
// Benachrichtigen Sie das Mediatorobjekt, wenn Sie mit anderen Kollegen kommunizieren müssen
getMediator().changed(this);
}
}
Verwenden Sie Ihren Computer, um Filme anzusehen
Im täglichen Leben nutzen wir häufig Computer, um Filme anzusehen. Lassen Sie uns diesen Prozess beschreiben. Nach der Vereinfachung gehen wir davon aus, dass es den folgenden interaktiven Prozess gibt:
(1) Zuerst muss das optische Laufwerk die Daten auf der optischen Disc lesen und dann dem Motherboard mitteilen, dass sich sein Status geändert hat.
(2) Das Motherboard erhält die Daten vom optischen Laufwerk und übergibt sie zur Analyse und Verarbeitung an die CPU.
(3) Nachdem die CPU die Verarbeitung abgeschlossen hat, teilt sie die Daten in Videodaten und Audiodaten auf und benachrichtigt das Motherboard, dass die Verarbeitung abgeschlossen ist.
(4) Das Motherboard erhält die von der CPU verarbeiteten Daten und leitet sie an die Grafikkarte bzw. die Soundkarte weiter, um das Video anzuzeigen und Töne zu erzeugen.
Um das Beispiel anhand des Mediatormusters umzusetzen, ist es notwendig, zwischen Kollegenobjekten und Mediatorobjekten zu unterscheiden. Offensichtlich ist das Motherboard der Vermittler, und Zubehör wie optische Laufwerke, Soundkarten, CPUs und Grafikkarten sind alle Kollegen.
Quellcode
Der Kopiercode der abstrakten Kollegenklasse lautet wie folgt:
öffentliche abstrakte Klasse Kollege {
//Halten Sie ein Mediatorobjekt
privater Mediator; Mediator;
/**
*Konstrukteur
*/
öffentlicher Kollege(Mediator Mediator){
this.mediator = Vermittler;
}
/**
* Holen Sie sich das Mediatorobjekt, das der aktuellen Kollegenklasse entspricht
*/
öffentlicher Mediator getMediator() {
Rückkehrvermittler;
}
}
Kollegenklasse - Kopiercode des optischen Laufwerks lautet wie folgt:
öffentliche Klasse CDDriver erweitert Colleague{
//Daten vom optischen Laufwerk gelesen
private String data = "";
/**
*Konstrukteur
*/
public CDDriver(Mediator mediator) {
Super(Vermittler);
}
/**
* Holen Sie sich die von der Disc gelesenen Daten
*/
öffentlicher String getData() {
Rückgabedaten;
}
/**
* CD lesen
*/
public void readCD(){
//Vor dem Komma stehen die im Video angezeigten Daten und nach dem Komma der Ton
this.data = „One Piece, ich bin fest entschlossen, der Piratenkönig zu sein“;
//Benachrichtigen Sie das Motherboard, dass sich sein Status geändert hat
getMediator().changed(this);
}
}
Kollegenklasse – CPU
Kopieren Sie den Codecode wie folgt:
CPU der öffentlichen Klasse erweitert Colleague {
//Videodaten zerlegt
private String videoData = "";
//Zerlegte Tondaten
private String soundData = "";
/**
*Konstrukteur
*/
öffentliche CPU(Mediator-Mediator) {
Super(Vermittler);
}
/**
* Erhalten Sie zerlegte Videodaten
*/
öffentlicher String getVideoData() {
videoData zurückgeben;
}
/**
* Holen Sie sich die zerlegten Klangdaten
*/
öffentlicher String getSoundData() {
return soundData;
}
/**
* Verarbeiten Sie die Daten und teilen Sie die Daten in Audio- und Videodaten auf
*/
public voidexecuteData(String data){
//Zerlegen Sie die Daten. Die Vorderseite sind Videodaten und die Rückseite sind Audiodaten.
String[] array = data.split(",");
this.videoData = array[0];
this.soundData = array[1];
// Benachrichtigen Sie das Motherboard, dass die CPU die Arbeit abgeschlossen hat
getMediator().changed(this);
}
}
Kollegenklasse - Der Code zum Kopieren der Grafikkarte lautet wie folgt:
öffentliche Klasse VideoCard erweitert Kollege {
/**
*Konstrukteur
*/
public VideoCard(Mediator mediator) {
Super(Vermittler);
}
/**
* Videodaten anzeigen
*/
public void showData(String data){
System.out.println("Sie sehen: " + data);
}
}
Kollegenklasse - Der Code zum Kopieren der Soundkarte lautet wie folgt:
öffentliche Klasse SoundCard erweitert Colleague {
/**
*Konstrukteur
*/
öffentliche SoundCard(Mediator mediator) {
Super(Vermittler);
}
/**
* Erstellen Sie Sounds basierend auf Audiodaten
*/
public void soundData(String data){
System.out.println("Voiceover: " + data);
}
}
Der Kopiercode der abstrakten Mediatorklasse lautet wie folgt:
öffentliche Schnittstelle Mediator {
/**
* Das Kollegenobjekt benachrichtigt die Mediatormethode, wenn es sich ändert.
* Lassen Sie den Mediator für die entsprechenden Interaktionen mit anderen Kollegenobjekten verantwortlich sein
*/
öffentliche Leere geändert (Kollege c);
}
Der spezifische Kopiercode der Mediatorklasse lautet wie folgt:
Die öffentliche Klasse MainBoard implementiert Mediator {
//Sie müssen die Kollegenklasse kennen, mit der Sie interagieren möchten – die Klasse des optischen Laufwerks
privater CDDriver cdDriver = null;
//Sie müssen die Kollegenklasse kennen, mit der Sie interagieren möchten – die CPU-Klasse
private CPU cpu = null;
//Sie müssen die Klasse der Kollegen kennen, mit denen Sie interagieren möchten – die Grafikkartenklasse
private VideoCard videoCard = null;
//Sie müssen die Klasse der Kollegen kennen, mit denen Sie interagieren möchten – die Soundkartenklasse
private SoundCard soundCard = null;
public void setCdDriver(CDDriver cdDriver) {
this.cdDriver = cdDriver;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
@Override
öffentliche Leere geändert(Kollege c) {
if(c Instanz von CDDriver){
//Zeigt an, dass das optische Laufwerk Daten gelesen hat
this.opeCDDriverReadData((CDDriver)c);
}else if(c Instanz der CPU){
this.opeCPU((CPU)c);
}
}
/**
* Behandeln Sie die Interaktion mit anderen Objekten, nachdem das optische Laufwerk Daten gelesen hat
*/
private void opeCDDriverReadData(CDDriver cd){
//Zuerst die vom optischen Laufwerk gelesenen Daten abrufen
String data = cd.getData();
// Übertragen Sie diese Daten zur Verarbeitung an die CPU
cpu.executeData(data);
}
/**
* Behandeln Sie die Interaktion zwischen der CPU und anderen Objekten nach der Datenverarbeitung
*/
private void opeCPU(CPU cpu){
// Zuerst die von der CPU verarbeiteten Daten abrufen
String videoData = cpu.getVideoData();
String soundData = cpu.getSoundData();
// Übertragen Sie diese Daten zur Anzeige auf die Grafikkarte und die Soundkarte
videoCard.showData(videoData);
soundCard.soundData(soundData);
}
}
Der Kopiercode der Client-Klasse lautet wie folgt:
öffentliche Klasse Client {
public static void main(String[] args) {
//Mediator erstellen – Motherboard
MainBoard-Mediator = new MainBoard();
//Kollegenklasse erstellen
CDDriver cd = neuer CDDriver(Mediator);
CPU CPU = neue CPU (Vermittler);
VideoCard vc = neue VideoCard(Mediator);
SoundCard sc = neue SoundCard(Vermittler);
//Teilen Sie dem Mediator alle Kollegen mit
mediator.setCdDriver(cd);
mediator.setCpu(cpu);
mediator.setVideoCard(vc);
mediator.setSoundCard(sc);
// Beginnen Sie mit der Wiedergabe des Films, legen Sie die Disc in das optische Laufwerk ein und das optische Laufwerk beginnt mit dem Lesen der Disc
cd.readCD();
}
}
Die Laufergebnisse sind wie folgt:
Vorteile des Mediator-Musters
● lose Kupplung
Das Mediatormuster kapselt die Interaktionen zwischen mehreren Kollegenobjekten im Mediatorobjekt, wodurch die Kollegenobjekte lose gekoppelt werden und grundsätzlich komplementäre Abhängigkeiten erreicht werden. Auf diese Weise können Kollegenobjekte unabhängig voneinander geändert und wiederverwendet werden, anstatt wie bisher „eine Stelle zu verschieben und den gesamten Körper zu beeinträchtigen“.
● Zentralisierte Steuerung der Interaktionen
Die Interaktionen mehrerer Kollegenobjekte werden zur zentralen Verwaltung im Mediatorobjekt gekapselt, sodass Sie bei einer Änderung dieses interaktiven Verhaltens nur das Mediatorobjekt ändern müssen. Wenn es sich natürlich um ein bereits fertiggestelltes System handelt, erweitern Sie das Mediatorobjekt. und jede Kollegenklasse muss nicht geändert werden.
● Aus Viele-zu-Viele wird Eins-zu-Viele
Wenn das Vermittlermuster nicht verwendet wird, ist die Beziehung zwischen Kollegenobjekten normalerweise eine Viele-zu-Viele-Beziehung. Nach der Einführung des Vermittlerobjekts wird die Beziehung zwischen dem Vermittlerobjekt und dem Kollegenobjekt normalerweise zu einer Zwei-Wege-Eins-zu-Viele-Beziehung. Dadurch ist die Beziehung zwischen den Objekten einfacher zu verstehen und umzusetzen.
Nachteile des Mediator-Musters
Ein möglicher Nachteil des Mediatormodells ist die übermäßige Zentralisierung. Wenn die Interaktion zwischen Kollegenobjekten sehr groß und komplex ist und sich all diese Komplexitäten auf den Mediator konzentrieren, wird das Mediatorobjekt sehr komplex und schwierig zu verwalten und zu warten.