Domanda

Ho una classe che incapsula le comunicazioni socket tcp con un server. Per ogni messaggio di comando inviato al server, il server invierà un messaggio di risposta che invariabilmente contiene un codice di risposta (OK, Fail). Usando la mia classe, ogni comando può essere eseguito sia sync che asincrono.

Esistono fondamentalmente due tipi di eccezioni che possono verificarsi: un "errore"; ciò è causato da una disconnessione o da un altro errore non recuperabile e un'eccezione imprevista come "buffer di invio è pieno". In caso di errore, nessun comando può continuare o riprovare o altro fino a quando non viene ristabilita la connessione. In caso di risposta non riuscita o addirittura di eccezione, il comando può essere riprovato ...

Quindi, in questo momento i miei metodi di comando di sincronizzazione restituiscono un enum che può avere i seguenti valori: OK, Fail, Fault. Se si verifica un'eccezione, viene semplicemente sollevata nel thread chiamante (in un comando di sincronizzazione). Per i comandi asincroni, il valore enum della proprietà Result può contenere un valore aggiuntivo: OK, Fail, Fault o Exception e il callback può accedere all'oggetto eccezione reale tramite la proprietà Exception dell'oggetto comando.

Cosa ne pensi di questa strategia? Sono tentato di non aumentare affatto le eccezioni per i comandi di sincronizzazione e di registrare semplicemente l'eccezione internamente e restituire invece il quarto valore enum perché è tutto ciò che farò davvero con le eccezioni in un determinato caso ... Oppure, non dovrei usare codici di risultato e sollevare eccezioni in tutti i casi, anche errori?

Grazie.

È stato utile?

Soluzione

Penso che la tua strategia sia sostanzialmente solida.

Tieni presente che lo scopo di Eccezioni è di gestire condizioni eccezionali. Più vicino alla fonte del problema, meglio è.

Nel tuo caso, sembra che la tua strategia sia qualcosa del tipo " In questo momento non ha funzionato. Riprova " ;. Non vedo un motivo per sollevare davvero delle eccezioni.

Se gestire un socket chiuso fosse qualcosa che richiedeva un flusso totalmente diverso nel codice, allora forse le eccezioni avrebbero senso. Dalla tua descrizione, non è proprio così.

La mia filosofia sulle eccezioni è che dovrebbero essere per condizioni eccezionali che non puoi davvero affrontare. Una presa chiusa? Hmm ... quante volte Internet va a casa mia ...

Altri suggerimenti

La mia preferenza è lanciare un'eccezione ogni volta che il metodo non completa correttamente la sua missione. Quindi, se io, il chiamante, chiamo yourObject.UploadFile (), supporrò che il file sia stato caricato correttamente al ritorno della chiamata. Se non riesce per qualsiasi motivo, mi aspetto che il tuo oggetto genererà un'eccezione. Se vuoi distinguere tra comandi che posso riprovare e comandi che non dovrei riprovare, metti quelle informazioni nell'eccezione e posso decidere come reagire di conseguenza.

Quando chiami yourObject.BeginAsyncUploadFile (), mi aspetto lo stesso comportamento tranne che dovrei aspettare su IAsyncResult o oggetto equivalente per scoprire se il caricamento del file è riuscito o meno e quindi controllare un'eccezione / errore in caso contrario.

I codici risultato e le eccezioni possono entrambi funzionare correttamente. È una questione di gusti personali (e il gusto degli altri nella tua squadra). Le eccezioni hanno alcuni vantaggi, specialmente in impostazioni più complesse, ma nelle tue impostazioni sembra abbastanza semplice che i codici di ritorno funzionino bene.

Alcune persone si schiumeranno in bocca e insisteranno sulle eccezioni, ma nel mio progetto le persone apprezzano la semplicità dei codici di ritorno, rendendole la scelta migliore in generale.

Questa è una domanda piuttosto interessante. Pertanto, probabilmente non esiste una risposta "corretta al 100%" e dipende principalmente da come pensi che il codice che utilizza la tua funzione debba essere strutturato.

Per come la vedo io, usi le eccezioni solo quando vuoi fornire al codice che chiama la tua funzione un modo per sfuggire con grazia da una situazione "disastrosa". Quindi, nel mio codice di solito lancio un'eccezione quando succede qualcosa di veramente, davvero orribile e il chiamante deve sapere.

Ora, se ciò che hai è una situazione normale e prevista, dovresti probabilmente restituire un valore di errore. In questo modo il codice sa che deve "provare di più", ma non sarà compromesso da quello che è successo.

Nel tuo caso, ad esempio, potresti considerare i timeout come qualcosa previsto e quindi restituire un codice di errore e problemi più gravi (come un buffer di invio completo) in cui il codice chiamante deve eseguire alcune azioni extra per tornare indietro a "normale" come eccezione.

Ma poi, la bellezza è negli occhi di chi guarda, e alcune persone ti diranno di usare solo eccezioni, altri (principalmente programmatori C) di usare solo codici di ritorno. Ricorda, le eccezioni dovrebbero essere sempre eccezionali. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top