1. Cos'è il Pattern Mediator
Il Pattern Mediator è un modello di progettazione comportamentale che riduce le dipendenze dirette tra gli oggetti trasferendo la loro comunicazione a un oggetto mediatore. Nel Pattern Mediator, gli oggetti non comunicano più direttamente tra loro, ma piuttosto attraverso l'oggetto mediatore.
2. Caratteristiche e vantaggi del Pattern Mediator
Le caratteristiche e i vantaggi del Pattern Mediator sono i seguenti:
- Riduce il coupling diretto tra gli oggetti, riducendo la complessità del sistema.
- Semplifica la comunicazione tra gli oggetti facendo sì che un oggetto mediatore gestisca la loro comunicazione.
- Centralizza il controllo delle interazioni tra gli oggetti, facilitando l'estensione e la manutenzione.
3. Esempi reali del Pattern Mediator
Il Pattern Mediator ha molte applicazioni in scenari reali. Ad esempio, in un sistema di pianificazione dell'aeroporto, il dispatcher agisce come mediatore, mentre i diversi moduli come gli aerei e il traffico a terra fungono da classi colleghi che comunicano e si coordinano tramite il dispatcher.
4. Implementazione del Pattern Mediator in Golang
4.1 Introduzione al diagramma delle classi UML
Di seguito è riportato il diagramma delle classi UML per il Pattern Mediator in Golang:
4.2 Introduzione all'esempio
In questo esempio, implementeremo un'applicazione di chat room semplice utilizzando il Pattern Mediator per gestire la comunicazione tra utenti diversi.
4.3 Implementazione Passo 1: Definizione dell'Interfaccia Mediatore e Mediatore Concreto
Innanzitutto, definiamo un'interfaccia mediatore e una classe mediatore concreta:
type Mediatore interface {
registraCollega(collega Collega)
inviaMessaggio(messaggio string, collega Collega)
}
type MediatoreConcreto struct {
colleghi map[string]Collega
}
func (m *MediatoreConcreto) registraCollega(collega Collega) {
m.colleghi[collega.getNome()] = collega
}
func (m *MediatoreConcreto) inviaMessaggio(messaggio string, collega Collega) {
for _, c := range m.colleghi {
if c != collega {
c.riceviMessaggio(messaggio)
}
}
}
4.4 Implementazione Passo 2: Definizione dell'Interfaccia Collega e Collega Concreto
Successivamente, definiamo un'interfaccia collega e classi collega concrete:
type Collega interface {
riceviMessaggio(messaggio string)
inviaMessaggio(messaggio string)
getNome() string
}
type CollegaConcretoA struct {
mediatore Mediatore
nome string
}
func (c *CollegaConcretoA) riceviMessaggio(messaggio string) {
fmt.Printf("%s ha ricevuto il messaggio: %s\n", c.nome, messaggio)
}
func (c *CollegaConcretoA) inviaMessaggio(messaggio string) {
c.mediatore.inviaMessaggio(messaggio, c)
}
func (c *CollegaConcretoA) getNome() string {
return c.nome
}
type CollegaConcretoB struct {
mediatore Mediatore
nome string
}
func (c *CollegaConcretoB) riceviMessaggio(messaggio string) {
fmt.Printf("%s ha ricevuto il messaggio: %s\n", c.nome, messaggio)
}
func (c *CollegaConcretoB) inviaMessaggio(messaggio string) {
c.mediatore.inviaMessaggio(messaggio, c)
}
func (c *CollegaConcretoB) getNome() string {
return c.nome
}
4.5 Implementazione Passo 3: Gestione dei Colleghi nel Mediatore
Nella classe mediatore specifica, dobbiamo implementare il metodo registraCollega
e il metodo inviaMessaggio
per gestire la comunicazione tra le classi collega:
func main() {
mediatore := &MediatoreConcreto{
colleghi: make(map[string]Collega),
}
collegaA := &CollegaConcretoA{
mediatore: mediatore,
nome: "Collega A",
}
collegaB := &CollegaConcretoB{
mediatore: mediatore,
nome: "Collega B",
}
mediatore.registraCollega(collegaA)
mediatore.registraCollega(collegaB)
collegaA.inviaMessaggio("Ciao, Mondo!")
collegaB.inviaMessaggio("Ciao a tutti!")
}
Nella funzione main
, creiamo un oggetto mediatore specifico e due oggetti collega specifici, quindi registriamo gli oggetti collega tramite l'oggetto mediatore e eseguiamo un test di comunicazione.