Padrão Mediador em Padrões de Comportamento

Em sistemas complexos, onde múltiplos objetos precisam interagir entre si, a comunicação direta pode criar uma teia de dependências de difícil manutenção. O Padrão Mediador soluciona isso introduzindo um objeto central que encapsula a lógica de interação entre os componentes. Essa abordagem transforma um relacionamento muitos-para-muitos caótico em uma estrutura organizada de um-para-muitos, promovendo baixo acoplamento entre as partes envolvidas.

A definição formal do padrão descreve como ele encapsula um conjunto de objetos com interações variáveis. A mediação garante que os objetos não se comuniquem diretamente, referenciando apenas ao mediador. Quando as regras de interação mudam, apenas o mediador necessita de ajustes, permitindo que as partes individuais sejam modificadas ou reutilizadas de forma independente.

O cenário ideal para aplicar este padrão surge quando múltiplos objetos apresentam comunicação complexa e interdependente. Alterar o comportamento de uma classe frequentemente exige mudanças cascata em diversas outras. O mediador centraliza esse controle, simplificando a manutenção e aumentando a flexibilidade do sistema.

Um exemplo prático é um sistema de controle residencial inteligente. Diferentes dispositivos — como termosatto, iluminação, fechaduras e alarmes — precisam coordenar suas ações (ex: ligar o ar-condicionado quando a temperatura sobe, ou desligar as luzes ao ativar o modo noturno). Um controlador central atua como mediador, processando eventos de um dispositivo e orquestrando as respostas dos demais.

Estrutura e Implementação

Primeiro, definimos uma interface abstrata para o mediador, que declara métodos para comunicação genérica.

// Interface do Mediador
public interface IMediadorResidencial {
    void notificar(DispositivoBase remetente, string evento);
}

Em seguida, criamos a classe conncreta do mediador, que contém referências para todos os dispositivos e a lógica de roteamento das ações.

// Mediador Concreto: Central de Controle
public class ControladorCentral : IMediadorResidencial {
    private Termostato _termometro;
    private Iluminacao _iluminacao;
    private SistemaAlarme _alarme;

    public void RegistrarTermostato(Termostato t) => _termometro = t;
    public void RegistrarIluminacao(Iluminacao i) => _iluminacao = i;
    public void RegistrarAlarme(SistemaAlarme a) => _alarme = a;

    public void notificar(DispositivoBase remetente, string evento) {
        if (remetente == _termometro && evento == "temperaturaAlta") {
            _iluminacao.AtivarModoNoite();
        }
        else if (remetente == _alarme && evento == "ativado") {
            _iluminacao.DesligarTodas();
        }
        // ... outras regras de interação
    }
}

A classe base dos colegas (dispositivos) mantém uma referência ao mediador.

// Classe Base para os Colaboradores
public abstract class DispositivoBase {
    protected IMediadorResidencial _mediador;

    public DispositivoBase(IMediadorResidencial mediador) {
        _mediador = mediador;
    }

    public void Enviar(string evento) {
        _mediador.notificar(this, evento);
    }

    public abstract void ReceberOrdem(string ordem);
}

As classes concretas dos dispositivos herdam da base e implementam suas lógicas específicas.

// Dispositivo Concreto: Termostato
public class Termostato : DispositivoBase {
    public Termostato(IMediadorResidencial m) : base(m) { }

    public void MonitorarTemperatura(int temp) {
        if (temp > 25) {
            Console.WriteLine("Termostato: Temperatura alta detectada.");
            Enviar("temperaturaAlta");
        }
    }

    public override void ReceberOrdem(string ordem) {
        // Lógica específica do termostato ao receber uma ordem
    }
}

// Dispositivo Concreto: Iluminação
public class Iluminacao : DispositivoBase {
    public Iluminacao(IMediadorResidencial m) : base(m) { }

    public void AtivarModoNoite() {
        Console.WriteLine("Iluminação: Modo noturno ativado.");
    }

    public void DesligarTodas() {
        Console.WriteLine("Iluminação: Todas as luzes desligadas.");
    }

    public override void ReceberOrdem(string ordem) { /* ... */ }
}

No teste de integração, conectamos os dispositivos através do mediador e disparamos uma ação para observar o efeito em cascata controlado.

// Teste de integração
public class TesteSistemaResidencial {
    public static void Executar() {
        var central = new ControladorCentral();
        
        var temp = new Termostato(central);
        var luzes = new Iluminacao(central);
        var alarme = new SistemaAlarme(central);

        central.RegistrarTermostato(temp);
        central.RegistrarIluminacao(luzes);
        central.RegistrarAlarme(alarme);

        // Simula uma alteração de estado
        temp.MonitorarTemperatura(28); // Deve ativar o modo noturno das luzes
    }
}

Nesta estrutura, os dispositivos não interagem diretamente. O Termostato apenas notifica o mediador sobre um evento. O ControladorCentral contém a inteligência para decidir que a Iluminacao deve ser acionada. Se a regra mudar, por exemplo, para também abrir uma janela, apenas a classe do mediador é alterada.

Tags: Padrões de Design padrão mediador padrões comportamentais baixo acoplamento arquitetura de software

Publicado em 6-3 03:48 por Thomas