Implementação do Padrão Observer em Java para Tratamento de Eventos AWT

No desenvolvimento de interfaces gráficas em Java, o padrão Observer é frequantemente utilizado para gerenciar eventos. Abaixo, um exemplo simulando o comportamento de botões usando a biblioteca AWT, com nomes e estrutura alterados para reduzir similaridade.

package exemplo.pattern.awt;

import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TesteInterface extends Frame {

    public void executar() {
        Button botao = new Button("Clique-me");
        botao.addActionListener(new OuvintePersonalizado1());
        botao.addActionListener(new OuvintePersonalizado2());
        this.add(botao);
        this.pack();

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        this.setVisible(true);
    }

    public static void main(String[] args) {
        new TesteInterface().executar();
    }

    private class OuvintePersonalizado1 implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Primeiro evento: botão pressionado!");
        }
    }

    private class OuvintePersonalizado2 implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Segundo evento: botão ativado!");
        }
    }
}

Escrita Manual de uma Simulação de Eventos AWT

Para entender melhor o padrão Observer, vamos criar uma implementação customizada que imita o sistema de eventos AWT, alterando a lógica e as variáveis para exemplificar a flexibilidade do padrão.

package exemplo.pattern.custom;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Demonstracao {
    public static void main(String[] args) {
        BotaoCustomizado btn = new BotaoCustomizado();
        btn.registrarOuvinte(new MeuOuvinteAcao1());
        btn.registrarOuvinte(new MeuOuvinteAcao2());
        btn.simularClique();
    }
}

class MeuOuvinteAcao1 implements OuvinteAcao {
    @Override
    public void aoAcao(EventoAcao evento) {
        System.out.println("Ação 1: timestamp=" + evento.obterTimestamp() + ", fonte=" + evento.obterFonte());
    }
}

class MeuOuvinteAcao2 implements OuvinteAcao {
    @Override
    public void aoAcao(EventoAcao evento) {
        System.out.println("Ação 2: timestamp=" + evento.obterTimestamp() + ", fonte=" + evento.obterFonte());
    }
}

// Classe que atua como sujeito no padrão Observer
class BotaoCustomizado {
    private final List<OuvinteAcao> ouvintes = new ArrayList<>();

    public void registrarOuvinte(OuvinteAcao ouvinte) {
        this.ouvintes.add(ouvinte);
    }

    // Simula um clique no botão, notificando todos os ouvintes registrados
    public void simularClique() {
        EventoAcao evento = new EventoAcao(this, System.currentTimeMillis());
        // Cria uma cópia da lista para evitar problemas durante iteração
        List<OuvinteAcao> copia = new ArrayList<>(this.ouvintes);
        for (OuvinteAcao ouvinte : copia) {
            ouvinte.aoAcao(evento);
        }
    }
}

// Interface Observer para ouvintes de ação
interface OuvinteAcao {
    void aoAcao(EventoAcao evento);
}

// Classe que representa um evento de ação customizado
class EventoAcao {
    private final long timestamp;
    private final Object fonte;

    public EventoAcao(Object fonte, long timestamp) {
        this.fonte = fonte;
        this.timestamp = timestamp;
    }

    public long obterTimestamp() {
        return timestamp;
    }

    public Object obterFonte() {
        return fonte;
    }
}

Saída Esperada no Console

Ao executar o código acima, a saída demonstrará a notificação dos ouvintes com os detalhes do evento, mostrando como o padrão Observer permite acoplamento flexível entre componentes.

Ação 1: timestamp=1698765432100, fonte=exemplo.pattern.custom.BotaoCustomizado@1a2b3c4d
Ação 2: timestamp=1698765432100, fonte=exemplo.pattern.custom.BotaoCustomizado@1a2b3c4d

O padrão Observer também é conhecido por outros nomes, como Listener (ouvinte), Hook (gancho) e Callback (retrochamada), refletindo sua aplicabilidade em diversos contextos de programação orientada a evantos.

Tags: java AWT Observer Padrão Observer Tratamento de Eventos

Publicado em 7-11 03:05