Como lidar com exceções de ouvintes acionados

5

Esta é mais uma questão de design e eu esperava obter vantagens e opiniões sobre o que faz sentido.

ANTECEDENTES

Imagine algo que contenha um ou mais ouvintes de evento. De vez em quando a coisa dispara eventos para seus ouvintes.

PROBLEMA

O problema é claro que os ouvintes que seguem depois de um ouvinte que joga nunca vai saber sobre o evento. Isso significa que a ordem dos ouvintes é um problema.

SOLUÇÃO # 1

Execute todos os ouvintes pegando quaisquer exceções lançadas. Isso significa que todos os ouvintes são disparados, mas em si mesmos apresentam outros problemas.

O que deve ser feito com exceções capturadas?

  • Uma opção é pegá-los todos e depois de disparar todos os eventos, lançar outra exceção que contém todos os problemas. ++
  • A outra opção é logar ~~
  • O último é simplesmente ignorar essas exceções. -
  • Ouvintes são executados isoladamente, o que é bom. ++

SOLUÇÃO # 2

Esta opção é simplista e simplesmente permite que qualquer exceção lançada de um ouvinte escape, resultando em que os ouvintes restantes nunca sejam acionados. Problemas com esta abordagem significam que

  • a ordem dos ouvintes é significativa (-)
  • simples de implementar (+).
  • antes que os ouvintes possam afetar o chamador

Q

Qual abordagem faz sentido e causa o menor número de problemas. Realmente faz sentido isolar os ouvintes para que eles recebam eventos, mas não podem fazer com que uma operação em execução seja cancelada se eles forem acionados?

    
por mP01 12.09.2011 / 07:30
fonte

2 respostas

7

Alguns pontos a considerar:

Os ouvintes devem se comportar de maneira bem comportada, protegendo a execução do próprio código de permitir que as exceções escapem para o exterior.

O evento firer (?), que é o único que dispara o evento, não tem interesse em fazer o que os ouvintes fazem com ele. Seu único trabalho é garantir que todos os ouvintes possam ouvir sobre o evento. Isso significa que ele deve proteger contra um dos ouvintes fazendo qualquer coisa que impeça outros ouvintes de obter o evento. Então, sim, pegue exceções.

O firer de eventos não tem interesse em capturar exceções além de garantir que o mau comportamento de um ouvinte não afete outros ouvintes. Então, neste caso, "comer" a exceção poderia ser defendida. No entanto, comer exceções não ajuda ninguém, portanto, registrar a exceção com tantos detalhes sobre o ouvinte ofensivo quanto possível é o caminho a seguir.

Eu não faria o atirador coletar exceções e, finalmente, criar um acordo próprio. Muito simplesmente porque o firer fez o seu trabalho corretamente e não tem necessidade de lançar uma exceção. Registrando as exceções geradas por ouvintes mal-comportados, o firer já está fazendo sua parte em auxiliar qualquer depuração necessária. (Logs devem estar sempre livres de exceções ...).

    
por 12.09.2011 / 08:47
fonte
1

Normalmente, a fonte do evento (observável) é dissociada dos observadores. Então o design é algo como abaixo:

Observable -> (fires)-> Observer1,Observer2,Observer3...ObserverN

No entanto, se você precisar adicionar uma lógica extra, adicione mais uma indirecção usando uma classe ObserserProcessor.

Observable -> (fires)
           |->ObserverProcessor1-->(log each)--> Observer1 ... Observer9
           |->ObserverProcessor2-->(whatever)-->Observer10 ... Observer20

Dessa forma, sua lógica de observadores ainda é desacoplada da classe observável, mas agrupada bem, de modo que você ainda pode adicionar lógica de processamento extra no meio.

Espero que isso ajude.

    
por 12.09.2011 / 09:24
fonte