Arquitetura orientada a eventos em Java: como transformar caos em sinfonia de eventos
Imagine uma orquestra onde cada músico toca sua parte sem olhar para o maestro. Parece uma catástrofe? Pois não é — se os músicos reagem a eventos: entrada dos violinos, mudança de ritmo da bateria, pausa da flauta. É exatamente assim que funciona a Arquitetura orientada a eventos em Java — os componentes do sistema se comunicam através de eventos, sem se conhecerem diretamente.
Se você já escreveu um monólito onde cada chamada de método puxa uma cadeia de dependências, você conhece essa dor. A programação orientada a eventos em Java é um sopro de ar fresco. Vamos entender como transformar sua aplicação em um sistema flexível e escalável que não quebra à menor mudança de requisitos.
O que é arquitetura orientada a eventos e por que você precisa dela?
Event-driven architecture (EDA) é um padrão arquitetural onde os componentes do sistema interagem gerando e processando eventos. Um evento é um fato que ocorreu no sistema: o usuário clicou num botão, um novo pedido chegou, o processamento de um arquivo terminou.
A principal vantagem é o baixo acoplamento. O emissor do evento não sabe quem o processará. O processador não sabe quem o chamou. Isso proporciona uma flexibilidade incrível:
- Escalabilidade — é possível adicionar novos processadores sem mexer no código existente
- Tolerância a falhas — se um processador falhar, os outros continuam funcionando
- Assincronicidade — os eventos podem ser processados em segundo plano, sem bloquear o fluxo principal
- Testabilidade — cada componente é testado isoladamente
Em Java, a programação orientada a eventos é implementada através de diferentes mecanismos: desde o embutido java.util.EventListener até poderosos corretores de mensagens como Apache Kafka. Mas vamos começar pelo simples.
Padrão clássico Observer em Java
A maneira mais simples de implementar uma arquitetura orientada a eventos em Java é usar o padrão Observer. Há muito tempo, ainda no JDK 1.0, existiam as classes java.util.Observable e java.util.Observer. Mas elas estão obsoletas (deprecated desde o Java 9). A abordagem moderna é escrever suas próprias interfaces ou usar soluções prontas.
Aqui está um exemplo mínimo de abordagem orientada a eventos em Java puro:
// Definimos a interface do ouvinte de eventos@FunctionalInterfaceinterface OrderEventListener { void onOrderCreated(OrderEvent event);}
// Classe do eventoclass OrderEvent { private final String orderId; private final String customerEmail;
public OrderEvent(String orderId, String customerEmail) { this.orderId = orderId; this.customerEmail = customerEmail; }
public String getOrderId() { return orderId; }
public String getCustomerEmail() { return customerEmail; }}
// Fonte de eventosclass OrderService { private final List<OrderEventListener> listeners = new ArrayList<>();
public void addListener(OrderEventListener listener) { listeners.add(listener); }
public void removeListener(OrderEventListener listener) { listeners.remove(listener); }
public void createOrder(String customerEmail, String product) { // Lógica de criação do pedido String orderId = UUID.randomUUID().toString(); System.out.println("Pedido " + orderId + " criado para " + customerEmail);
// Notificamos todos os ouvintes OrderEvent event = new OrderEvent(orderId, customerEmail); listeners.forEach(listener -> listener.onOrderCreated(event)); }}
// Processadores de eventosclass EmailNotificationListener implements OrderEventListener { @Override public void onOrderCreated(OrderEvent event) { System.out.pri