Penso che tutte le risposte che spiegano che non si dovrebbe avere una bandiera che controlli se viene generata o meno un'eccezione siano valide. Il loro consiglio sarebbe il mio consiglio a chiunque senta la necessità di porre quella domanda.
Volevo tuttavia sottolineare che esiste un'eccezione significativa a questa regola. Una volta che sei abbastanza avanzato per iniziare a sviluppare API che centinaia di altre persone useranno, ci sono casi in cui potresti voler fornire una tale bandiera. Quando scrivi un'API, non stai solo scrivendo ai puristi. Stai scrivendo a clienti reali che hanno desideri reali. Parte del tuo lavoro è renderli felici con la tua API. Questo diventa un problema sociale, piuttosto che un problema di programmazione, e talvolta i problemi sociali dettano soluzioni che sarebbero meno che ideali come soluzioni di programmazione da sole.
Potresti scoprire di avere due utenti distinti della tua API, uno dei quali richiede eccezioni e uno che non lo fa. Un esempio di vita reale in cui ciò potrebbe accadere è con una libreria utilizzata sia nello sviluppo che su un sistema incorporato. Negli ambienti di sviluppo, gli utenti vorranno probabilmente avere eccezioni ovunque. Le eccezioni sono molto popolari per la gestione di situazioni impreviste. Tuttavia, sono vietati in molte situazioni incorporate perché sono troppo difficili da analizzare i vincoli in tempo reale. Quando in realtà ti preoccupi non solo del tempo medio impiegato per eseguire la tua funzione, ma del tempo necessario per qualsiasi divertimento individuale, l'idea di svolgere la pila in qualsiasi luogo arbitrario è molto indesiderabile.
Un esempio di vita reale per me: una biblioteca di matematica. Se la tua libreria matematica ha una Vector
classe che supporta ottenere un vettore di unità nella stessa direzione, devi essere in grado di dividere per grandezza. Se la grandezza è 0, hai una divisione per zero. In fase di sviluppo , vuoi catturarli . Non vuoi davvero una divisione sorprendente per gli 0 in giro. Lanciare un'eccezione è una soluzione molto popolare per questo. Non succede quasi mai (è un comportamento davvero eccezionale), ma quando lo fa, lo vuoi sapere.
Sulla piattaforma integrata, non si desidera tali eccezioni. Avrebbe più senso fare un controllo if (this->mag() == 0) return Vector(0, 0, 0);
. In effetti, lo vedo nel vero codice.
Ora pensa dal punto di vista di un'azienda. Puoi provare a insegnare due modi diversi di utilizzare un'API:
// Development version - exceptions // Embeded version - return 0s
Vector right = forward.cross(up); Vector right = forward.cross(up);
Vector localUp = right.cross(forward); Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit(); Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit(); Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit() Vector localUpHat = localUp.tryUnit();
Questo soddisfa le opinioni della maggior parte delle risposte qui, ma dal punto di vista dell'azienda questo è indesiderabile. Gli sviluppatori incorporati dovranno imparare uno stile di codifica e gli sviluppatori dello sviluppo dovranno imparare un altro. Questo può essere piuttosto fastidioso e costringe le persone a un solo modo di pensare. Potenzialmente peggio: come si fa a dimostrare che la versione incorporata non include alcun codice di lancio delle eccezioni? La versione di lancio può facilmente confondersi, nascondendosi da qualche parte nel codice fino a quando non viene trovata da un costoso Failure Review Board.
Se invece hai una bandiera che attiva o disattiva la gestione delle eccezioni, entrambi i gruppi possono apprendere lo stesso identico stile di codifica. In effetti, in molti casi, puoi persino usare il codice di un gruppo nei progetti dell'altro gruppo. Nel caso in cui utilizzi questo codice unit()
, se in realtà ti interessa cosa succede in un caso di divisione per 0, dovresti aver scritto tu stesso il test. Pertanto, se lo si sposta su un sistema incorporato, dove si ottengono solo risultati negativi, tale comportamento è "sano di mente". Ora, dal punto di vista aziendale, alleno i miei programmatori una volta e usano le stesse API e gli stessi stili in tutte le parti della mia attività.
Nella stragrande maggioranza dei casi, vuoi seguire i consigli degli altri: usa modi di tryGetUnit()
dire simili o simili per funzioni che non generano eccezioni e restituisce invece un valore sentinella come null. Se ritieni che gli utenti potrebbero voler utilizzare sia il codice di gestione delle eccezioni sia il codice di gestione delle eccezioni fianco a fianco all'interno di un singolo programma, segui la tryGetUnit()
notazione. Tuttavia, esiste un caso angolare in cui la realtà degli affari può rendere migliore l'uso di una bandiera. Se ti trovi in quel caso d'angolo, non aver paura di lanciare le "regole" a margine. Ecco a cosa servono le regole!