1. Was ist das Mediator-Pattern
Das Mediator-Pattern ist ein Verhaltensmuster des Designs, das die direkten Abhängigkeiten zwischen Objekten reduziert, indem ihre Kommunikation an ein Mediator-Objekt übertragen wird. Im Mediator-Pattern kommunizieren Objekte nicht mehr direkt miteinander, sondern stattdessen über das Mediator-Objekt.
2. Merkmale und Vorteile des Mediator-Pattern
Die Merkmale und Vorteile des Mediator-Pattern sind wie folgt:
- Verringert die direkte Kopplung zwischen Objekten und reduziert damit die Systemkomplexität.
- Vereinfacht die Kommunikation zwischen Objekten, indem ein Mediator-Objekt die Kommunikation zwischen ihnen handhabt.
- Zentralisiert die Steuerung von Interaktionen zwischen Objekten, was die Erweiterung und Wartung erleichtert.
3. Beispiele aus der realen Welt des Mediator-Pattern
Das Mediator-Pattern findet viele Anwendungen in realen Szenarien. Zum Beispiel fungiert im Flughafenplanungssystem der Dispatcher als Mediator, während die verschiedenen Module wie Flugzeuge und Bodenverkehr als Kollegenklassen agieren und durch den Dispatcher kommunizieren und koordinieren.
4. Implementierung des Mediator-Pattern in Golang
4.1 Einführung in das UML-Klassendiagramm
Nachfolgend finden Sie das UML-Klassendiagramm für das Mediator-Pattern in Golang:
4.2 Beispiel Einführung
In diesem Beispiel implementieren wir eine einfache Chatroom-Anwendung unter Verwendung des Mediator-Patterns zur Verwaltung der Kommunikation zwischen verschiedenen Benutzern.
4.3 Implementierungsschritt 1: Definition von Mediator-Interface und konkretem Mediator
Zuerst definieren wir ein Mediator-Interface und eine konkrete Mediator-Klasse:
type Mediator interface {
registerColleague(colleague Colleague)
sendMessage(message string, colleague Colleague)
}
type ConcreteMediator struct {
colleagues map[string]Colleague
}
func (m *ConcreteMediator) registerColleague(colleague Colleague) {
m.colleagues[colleague.getName()] = colleague
}
func (m *ConcreteMediator) sendMessage(message string, colleague Colleague) {
for _, c := range m.colleagues {
if c != colleague {
c.receiveMessage(message)
}
}
}
4.4 Implementierungsschritt 2: Definition von Colleague-Interface und konkretem Kollegen
Als Nächstes definieren wir ein Kollegen-Interface und konkrete Kollegenklassen:
type Colleague interface {
receiveMessage(message string)
sendMessage(message string)
getName() string
}
type ConcreteColleagueA struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueA) receiveMessage(message string) {
fmt.Printf("%s hat die Nachricht empfangen: %s\n", c.name, message)
}
func (c *ConcreteColleagueA) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueA) getName() string {
return c.name
}
type ConcreteColleagueB struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueB) receiveMessage(message string) {
fmt.Printf("%s hat die Nachricht empfangen: %s\n", c.name, message)
}
func (c *ConcreteColleagueB) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueB) getName() string {
return c.name
}
4.5 Implementierungsschritt 3: Verwalten von Kollegen im Mediator
In der spezifischen Mediatorklasse müssen wir die Methode registerColleague
und die Methode sendMessage
implementieren, um die Kommunikation zwischen Kollegenklassen zu verwalten:
func main() {
mediator := &ConcreteMediator{
colleagues: make(map[string]Colleague),
}
colleagueA := &ConcreteColleagueA{
mediator: mediator,
name: "Kollege A",
}
colleagueB := &ConcreteColleagueB{
mediator: mediator,
name: "Kollege B",
}
mediator.registerColleague(colleagueA)
mediator.registerColleague(colleagueB)
colleagueA.sendMessage("Hallo, Welt!")
colleagueB.sendMessage("Hallo zusammen!")
}
In der main
-Funktion erstellen wir ein spezifisches Mediator-Objekt und zwei spezifische Kollegen-Objekte, registrieren die Kollegen-Objekte durch das Mediator-Objekt und führen anschließend einen Kommunikationstest durch.