1. O que é o Padrão Mediator
O Padrão Mediator é um padrão de design comportamental que reduz as dependências diretas entre objetos transferindo a comunicação deles para um objeto mediador. No Padrão Mediator, os objetos não se comunicam mais diretamente entre si, mas sim por meio do objeto mediador.
2. Características e Vantagens do Padrão Mediator
As características e vantagens do Padrão Mediator são as seguintes:
- Reduz o acoplamento direto entre objetos, reduzindo a complexidade do sistema.
- Simplifica a comunicação entre objetos, tendo um objeto mediador que gerencia a comunicação.
- Centraliza o controle das interações entre objetos, facilitando a extensão e manutenção.
3. Exemplos do Mundo Real do Padrão Mediator
O Padrão Mediator possui muitas aplicações em cenários da vida real. Por exemplo, em um sistema de agendamento de aeroportos, o despachante atua como o mediador, enquanto os diferentes módulos, como aviões e tráfego terrestre, atuam como classes colegas que se comunicam e coordenam por meio do despachante.
4. Implementação do Padrão Mediator em Golang
4.1 Introdução ao Diagrama de Classe UML
A seguir está o diagrama de classe UML para o Padrão Mediator em Golang:
4.2 Introdução do Exemplo
Neste exemplo, implementaremos uma aplicação de sala de chat simples usando o Padrão Mediator para gerenciar a comunicação entre diferentes usuários.
4.3 Passo 1 da Implementação: Definir a Interface do Mediator e o Mediator Concreto
Primeiro, definimos uma interface de mediador e uma classe de mediador concreta:
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 Passo 2 da Implementação: Definir a Interface do Colega e Colegas Concretos
Em seguida, definimos uma interface de colega e classes de colegas concretos:
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 recebeu a mensagem: %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 recebeu a mensagem: %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 Passo 3 da Implementação: Gerenciamento de Colegas no Mediator
Na classe mediador específica, precisamos implementar o método registerColleague
e o método sendMessage
para gerenciar a comunicação entre as classes colegas:
func main() {
mediator := &ConcreteMediator{
colleagues: make(map[string]Colleague),
}
colleagueA := &ConcreteColleagueA{
mediator: mediator,
name: "Colega A",
}
colleagueB := &ConcreteColleagueB{
mediator: mediator,
name: "Colega B",
}
mediator.registerColleague(colleagueA)
mediator.registerColleague(colleagueB)
colleagueA.sendMessage("Olá, Mundo!")
colleagueB.sendMessage("Oi, tudo bem?")
}
Na função main
, criamos um objeto mediador específico e dois objetos colegas específicos, registramos os objetos colegas por meio do objeto mediador e realizamos testes de comunicação.