Correlato a: Il gestore onError è migliore delle eccezioni?
Premessa
Sto scrivendo una parte del codice della libreria che esegue determinati compiti, per separare le preoccupazioni, abbiamo deciso che non dovremmo scrivere in un log o scrivere direttamente sul display, ma invece fornire un meccanismo di registrazione degli eventi che consenta l'ascolto del codice del client interessato agli eventi del suo ciclo di vita.
Fin qui tutto bene. Abbiamo un gestore di eventi per il registro e un gestore di eventi per la visualizzazione, vengono informati quando si verifica un evento e scrivono in modo indipendente sul log / display.
Quindi abbiamo finora (pseudo codice)
class MyLib(List<MYLibEventHandler> listeners)
class Display implements MYLibEventHandler
class Log implements MYLibEventHandler
Domanda
La domanda sollevata era: come informare i clienti delle eccezioni? Un modo di guardarlo è che un'eccezione può essere vista come solo un altro evento. È qualcosa di esterno che accade e ai clienti interessa sapere quando accade.
Quindi possiamo semplicemente aggiungere un altro evento per le eccezioni che ricevono l'oggetto eccezione. (possiamo rilanciare l'eccezione per consentire a qualsiasi altro costrutto try / catch di gestirlo, ma il log / display non sono in realtà che gestiscono l'eccezione, sono appena stati avvisati che è successo così possono fare ciò che vogliono con esso. Non possono davvero recuperare da esso)
D'altra parte, ha un cattivo odore. Un'eccezione non è un evento normale, è un'interruzione nel flusso, quindi possiamo dire che il nostro "main" catturerà eventuali eccezioni e passerà esplicitamente alle istanze Display
e Log
, al di fuori del meccanismo di invio dell'evento.
Questo odora anche perché abbiamo già un elenco di listener, ma chiamiamo esplicitamente il log e il display per gestire l'eccezione.
(Forse non dovrei essere allarmato dal fatto che il codice stia facendo qualcosa di "eccezionale" quando consegna una "eccezione", ma sente ancora l'odore di dover tenere traccia dei client due volte)
Quindi sono bloccato con un odore di codice, non importa quello che scelgo.
Esiste un modello di progettazione per gestire più listener / gestori per la stessa eccezione? try catch è una struttura molto "single listener" / "hierarchical", non sembra lo strumento giusto per un ampio scenario di "distribuzione". Forse una sorta di pattern AOP?
Il mio tentativo di rispondere a questo è che se ho un server remoto, con più client, e il server deve comunicare che si è verificata un'eccezione del server, non ci sarebbe stata alcuna domanda dato che il client non può realmente "provare / catturare" l'eccezione. Sarà più probabile che venga inviato come evento (ad esempio in Akka come oggetto Try). Anche in RMI, l'eccezione viene inviata più come un "evento" e solo in seguito attiva un RemoteException
localmente.
Esiste uno schema di progettazione conosciuto per gestire listener multipli, indipendenti e di sola lettura per un'eccezione (ad esempio, gli ascoltatori che non possono e non si ripristinano dall'eccezione, devono solo sapere che è successo)
Forse in questo caso, inviare l'eccezione come evento (e poi rilanciarlo) è la strada giusta da fare?