Coercizione errata o arresto anomalo sempre precoce

1

Il consenso generale sembra favorire l'approccio Crash Early , la fonte più affidabile è l'acclamato libro Pragmatic Programmer .

E mentre capisco e sono d'accordo con il consiglio in molte situazioni, mi chiedo se una volta che il programma è distribuito in produzione, non è anche valido semplicemente registrare un avviso e procedere con l'esecuzione?

In molti casi potrebbe essere meglio mostrare una risposta parziale o vuota rispetto a nessuna risposta. Immagina il modulo di scambio dello stack per recuperare domande simili, non è meglio mostrare alcuni risultati piuttosto che ottenere risultati?

Potrebbe un metodo che itera su una collezione, quando viene passato un valore nullo costringerlo in una collezione vuota e saltare in modo efficace l'esecuzione, invece di bloccarsi? O un metodo che riceve un numero negativo lo costringe al valore minimo / massimo applicabile, invece di schiantarsi?

    
posta Filipe Miguel Fonseca 15.12.2014 - 11:51
fonte

3 risposte

3

... I wonder if once the program is deployed in production, isn't it also valid to simply log a warning and proceed the execution?

Risposta breve: No.
Ogni funzione che scrivi viene eseguita nel suo unico piccolo mondo che conosce solo i valori dell'argomento passati ad esso. Può solo cambiare o reinterpretare l'intenzione di quei valori se capisce il mondo "fuori" da se stesso meglio del codice che è in realtà "là fuori", passando quei valori oscuri. (Suggerimento: è improbabile)

... isn't it best to show some results than no results at all?

"Ci sono indicazioni che questo nucleo di reattore nucleare sia scappato e stia per iniziare a fondere il suo modo attraverso il pavimento? Hmm, questo sta richiedendo troppo tempo, tornerò semplicemente" OK ".

OK, un esempio un po 'faceto, ma in questo caso particolare, allora sì, in realtà importa che riporti tutti i giusti risultati. Si tratta di ciò che è considerato "abbastanza buono"?

Could a method that iterates over a collection, when passed a null value coerce it into an empty collection and effectively skip execution, instead of crashing?

E fare cosa?
Una scatola di cioccolatini è un insieme di zero o più confetterie; dato una scatola e un appetito abbastanza grande, puoi "iterare" attraverso tutti loro. Come puoi che se non ti viene nemmeno data la scatola?

Alla tua funzione è stato detto di aspettarsi una collezione ma non è stato passato nulla. È davvero un buon momento per far lanciare un'eccezione; in questo modo, il codice chiamante diventa responsabile della gestione del pasticcio che ha appena creato, trasmettendo dati errati (mancanti).

Or a method that receives a negative number coerce it into the minimum/maximum applicable value, instead of crashing?

Perché un numero negativo causerebbe un arresto anomalo? Forse è un indicizzatore in una matrice o lista? A meno che non ci sia un motivo commerciale per consentire valori negativi (e, ammettiamolo, potrebbe esserci), ecco un altro buon motivo per "passare il tempo" verso l'alto, di nuovo al codice chiamante, per gentile concessione di un'altra Eccezione.

    
risposta data 15.12.2014 - 13:51
fonte
5

Come al solito, ci sono evidenti aspetti positivi e negativi alla coercizione. Farà funzionare il tuo programma in produzione, quando è debole e solo e non ha nessuno che gli tenga la mano; deve gestire tutte le condizioni in cui è messo tutto da solo, e l'alterazione del valore minimo è la cosa ovvia da fare. Se l'arresto o l'eliminazione di un task nel complesso sarebbe molto costoso o catastrofico per il tuo business, allora c'è un buon esempio per rendere il software robusto.

Ma questo è solo un lato della medaglia. A lungo termine, programmare in questo modo rende il tuo codice illeggibile, lungo, brutto e non gestibile. Se arriva un valore negativo, dovresti chiedertelo: perché? se proviene da input diretto dell'utente, perché il tuo front-end ha consentito al segno meno di essere al primo posto ? Se è da un valore interno, doveva succedere quello? Se no, perché è successo? C'è un difetto completamente diverso nel tuo programma che ha permesso questo? Perseguire e correggere tali errori migliorerà la qualità della base di codice molto più che aggiungere un'altra patch per un'altra condizione speciale che potrebbe causare un'eccezione.

Sfortunatamente, questi due approcci sono difficili da combinare. Il punto di test del software è di provarlo nelle situazioni in cui si troverà effettivamente, quindi scrivere codice complicato, sensibile agli errori in fase di sviluppo e quindi distribuire codice robusto non è possibile allo stesso tempo. Pertanto è importante che tu sia a conoscenza di tali compromessi, in modo che tu possa effettuare una chiamata di giudizio corretta, sia che si tratti di un'elaborazione robusta, indipendentemente da ciò che è più prezioso per te che di un codice ben progettato che riduce il numero di problemi sistemici. Questo è qualcosa che nessun runtime, nessuna politica di codifica e nemmeno il miglior forum online del programmatore può decidere per te.

    
risposta data 15.12.2014 - 11:59
fonte
2

Nei tuoi esempi non stai parlando di un fallimento anticipato, ma piuttosto di come gestire i casi di fallimento previsti.

Gestione dei casi di errore previsti

Hai fornito il modulo domande simili come esempio. Può essere consapevole del fatto che uno dei suoi sottomoduli potrebbe non essere in grado di fornire e quindi mostra solo il resto delle domande che ha ricevuto dai suoi sottomoduli. Un controesempio sarebbe un software medico per la ricerca di pazienti con sintomi simili. Non mostrerebbe solo il resto, ma stamperà un avvertimento che alcuni pazienti potrebbero non essere elencati a causa di qualche errore, ma continua comunque a funzionare e adempiere al suo compito, che sarebbe "stampare tutti i pazienti, o un messaggio di errore se è possibile stampare tutti i pazienti ". Questa è una differenza importante, ma non ha nulla a che fare con il fallimento presto. Si tratta di gestire i fallimenti attesi perché i moduli sono consapevoli di questo specifico fallimento. Nota che questo ha solo a che fare con le logiche di business, niente con la gestione tecnica.

Gestire casi di errore imprevisti (o meglio, non farlo ...)

Il sottomodulo per la consegna (parte di) domande simili potrebbe fallire perché, ad esempio, potrebbe aspettarsi che sia disponibile una connessione di rete. Se non ce n'è, potrebbe andare avanti e continuare a lavorare con una lista di domande di emtpy, ma ciò non è ragionevole - non ha alcun senso. Quindi, dato che non sa come gestire questa situazione, viene considerato come un errore imprevisto e quindi genera un'eccezione, interrompendo quindi il suo lavoro immediatamente, dicendo al chiamante che non può adempiere al suo contratto e fornire i risultati attesi. Quindi, invece di fingere di essere in grado di adempiere al suo contratto (e nel peggiore dei casi produrre errori di logica di business qualche tempo dopo) fallisce presto.

Quindi, per rispondere alla tua domanda: sì, puoi avere il tuo modulo domande simili per stampare solo alcune delle domande se non può recuperare tutto e seguire le linee guida per fallire il prima possibile, perché non si contraccambiano a vicenda .

Could a method that iterates over a collection, when passed a null value coerce it into an empty collection and effectively skip execution, instead of crashing?

Tuttavia, se il contratto del metodo dice "Mi aspetto una collezione e poi faccio qualcosa" e quindi riceve un valore nullo, dovrebbe fallire presto, perché non può completare il suo contratto. Se non fallisce presto e continua a fare cose, allora possono accadere cose brutte e non vedo alcun vantaggio. A meno che l'intero software non esploda a causa di un'eccezione di basso livello - ma in ogni caso è mal progettato e la funzione - correttamente fallendo velocemente - non è la radice del problema.

    
risposta data 15.12.2014 - 13:15
fonte