Se você já fez um app iOS crescer um pouco, provavelmente já encontrou este momento.
Uma tela tem cinco ou seis views: quando A muda, B também precisa mudar; quando B muda, C precisa ser ajustada.
Logo, as views passam a referenciar umas às outras diretamente e ficam enroladas como um novelo.
É exatamente isso que o padrão Mediator ajuda a organizar.
O padrão Mediator em Swift reduz o acoplamento fazendo os objetos se comunicarem apenas com um Mediator, sem referências diretas entre si.
Neste artigo, explico o que é o padrão Mediator, quando usá-lo e como implementá-lo em Swift com código de exemplo.
O que é o padrão Mediator?
Em uma frase:
Coloque um Mediator entre os objetos que precisam se comunicar e faça toda a conversa passar por ele.
Pense em uma torre de controle de aeroporto.
Se os aviões falassem pelo rádio “pouse primeiro” e “eu vou primeiro”, aconteceria um grande acidente.
Por isso, cada avião conversa apenas com a torre, que organiza a ordem.
Aqui, os aviões são os objetos do nosso código, e a torre é o Mediator.
O padrão Mediator resolve principalmente isto:
- Remover referências diretas: o objeto A não precisa conhecer B, C e D individualmente
- Concentrar a lógica de comunicação: regras complexas de interação ficam reunidas em um Mediator
- Aumentar a reutilização: objetos independentes são fáceis de reutilizar em outras telas
Quando usar o padrão Mediator?
Ele não é ideal para todas as situações. Considero adotá-lo quando vejo sinais como estes.
Quando os objetos conhecem demais uns aos outros, ou seja, ao abrir uma classe surgem referências em cadeia para vários outros objetos.
Outro sinal é precisar alterar vários objetos relacionados ao mesmo tempo para mudar uma única parte da lógica.
Os usos mais comuns são:
| Situação | Exemplo |
|---|---|
| UI de tela complexa | Vários botões e labels reagem em cadeia aos valores do formulário |
| Coordenação de componentes | Encaminhamento de mensagens entre participantes de uma sala de chat |
| Controle de workflow | Gerenciamento do estado das views em cada etapa do pagamento |
Por outro lado, se houver apenas dois ou três objetos e a relação for simples, é melhor não usar.
O Mediator pode crescer sem necessidade e virar um “God Object”.
Como implementar o padrão Mediator em Swift?
Vamos usar uma sala de chat como exemplo. Os participantes trocam mensagens pela sala (o Mediator), em vez de enviarem mensagens diretamente uns aos outros.
Primeiro, definimos o protocolo que o Mediator deve seguir e os participantes.
// Regras que o Mediator deve seguir
protocol ChatMediator {
func send(_ message: String, from user: User)
func add(_ user: User)
}
O ponto principal é que cada participante conhece apenas o Mediator e não referencia diretamente os outros participantes.
class User {
let name: String
weak var mediator: ChatMediator? // Evitar referências cíclicas
init(name: String) { self.name = name }
func send(_ text: String) {
mediator?.send(text, from: self) // Delegar ao Mediator
}
func receive(_ text: String) {
print("\(name) Recebido: \(text)")
}
}
Por fim, o Mediator cuida das regras reais de entrega: transmite a mensagem apenas para quem não a enviou.
class ChatRoom: ChatMediator {
private var users: [User] = []
func add(_ user: User) { users.append(user); user.mediator = self }
func send(_ message: String, from user: User) {
users.filter { $0 !== user }
.forEach { $0.receive("[\(user.name)] \(message)") }
}
}
Mesmo que o número de usuários cresça, não é preciso alterar a classe User. Só a ChatRoom conhece as regras de entrega.
Mediator vs. Observer: qual é a diferença?
Muita gente confunde esses dois padrões.
Resumindo, a diferença é esta.
| Categoria | Mediator | Observer |
|---|---|---|
| Direção | Comunicação muitos-para-muitos centralizada | Notificação um-para-muitos (publicação-assinatura) |
| Relação | Os objetos interagem por meio do Mediator | O observado notifica os observadores |
| Foco | Coordenação mútua complexa | Propagação de mudanças de estado |
Em termos simples, o Observer anuncia unilateralmente: “Eu mudei!”
O Mediator decide “quem deve fazer o quê nesta situação?” e coordena os objetos.
No Swift, Combine e NotificationCenter se aproximam da família Observer, enquanto o Mediator geralmente é implementado diretamente.
Perguntas frequentes (Q&A)
P. E se o Mediator ficar grande demais?
Como a lógica se concentra ali, o Mediator pode ficar inchado. Divida-o em vários Mediators por funcionalidade ou extraia a lógica interna para helpers separados.
P. Preciso usar weak obrigatoriamente?
Sim. Se participantes e Mediator referenciarem um ao outro fortemente, referências cíclicas causarão vazamento de memória. Deixe um dos lados como weak, como no exemplo.
P. Posso usar com SwiftUI?
Sim. Muitas vezes, o ViewModel atua na prática como Mediator entre as views. É natural coordenar o estado de várias views por meio de um único ViewModel.
Se seus objetos estão tão interligados que dá medo de mexer no código, experimente adicionar o padrão Mediator.
Basta criar um Mediator para deixar cada objeto muito mais leve e facilitar futuras adições de funcionalidades.
Recomendo aplicar o código de exemplo de hoje em um projeto pequeno. Ao escrever você mesmo, tudo fica claro. 😊
Continue lendo
- [Fundamentos de Swift #1] O que os Optionals do Swift realmente são: na verdade, enums (5 formas de desembrulhar na prática)
- [Fundamentos de Swift #2] Closures do Swift em detalhes: por que captura, [weak self] e @escaping andam juntos
- Mediator vs. Observer vs. Facade: comparação completa de 3 padrões de comunicação entre objetos

