Penso che tutte le risposte che spiegano che non si debba avere un flag che controlli se un'eccezione è lanciata o meno sono buone. Il loro consiglio sarebbe il mio consiglio a chiunque senta il bisogno di fare quella domanda.
Tuttavia, volevo sottolineare che esiste un'eccezione significativa a questa regola. Una volta che sei abbastanza avanzato per iniziare a sviluppare API che verranno utilizzate da centinaia di altre persone, ci sono casi in cui potresti voler fornire una tale bandiera. Quando stai scrivendo 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, ea volte i problemi sociali dettano soluzioni che sarebbero non ideali come soluzioni di programmazione per conto proprio.
Potresti scoprire di avere due utenti distinti della tua API, uno dei quali desidera eccezioni e uno che non lo fa. Un esempio di vita reale in cui ciò potrebbe verificarsi è con una libreria che viene utilizzata sia in fase di sviluppo che in un sistema embedded. Negli ambienti di sviluppo, gli utenti probabilmente vorranno avere eccezioni ovunque. Le eccezioni sono molto popolari per la gestione di situazioni impreviste. Tuttavia, sono proibiti in molte situazioni incorporate perché sono troppo difficili da analizzare intorno ai vincoli in tempo reale. Quando ci si preoccupa non solo del tempo medio necessario per eseguire la propria funzione, ma anche del tempo necessario per ogni singolo divertimento, l'idea di srotolare lo stack in qualsiasi luogo arbitrario è molto indesiderabile.
Un vero esempio di vita per me: una biblioteca matematica. Se la tua libreria matematica ha una classe Vector
che supporta il recupero di un vettore unitario nella stessa direzione, devi essere in grado di dividere per la grandezza. Se la magnitudine è 0, si ha una situazione di divisione per zero. Nello sviluppo vuoi catturare questi . Non vuoi davvero sorprendere il divario per 0 che gironzola. Lanciare un'eccezione è una soluzione molto popolare per questo. Non succede quasi mai (è un comportamento veramente eccezionale), ma quando lo fa, vuoi saperlo.
Sulla piattaforma integrata, non vuoi quelle eccezioni. Avrebbe più senso fare un controllo if (this->mag() == 0) return Vector(0, 0, 0);
. In effetti, lo vedo in codice reale.
Ora pensa dalla prospettiva di un'azienda. Puoi provare a insegnare due diversi modi 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 aziendale questo non è auspicabile. Gli sviluppatori incorporati dovranno imparare uno stile della codifica e gli sviluppatori di sviluppo dovranno imparare un altro. Questo può essere piuttosto fastidioso e costringe le persone a pensare in un modo. Potenzialmente peggiore: come si fa a dimostrare che la versione integrata non include alcun codice di lancio delle eccezioni? La versione di lancio può facilmente confondersi, nascondendosi da qualche parte nel codice fino a quando una costosa Failure Review Board lo trova.
Se, d'altra parte, hai una bandiera che attiva o disattiva la gestione delle eccezioni, entrambi i gruppi possono apprendere lo stesso identico stile di codifica. In molti casi, infatti, puoi persino utilizzare il codice di un gruppo nei progetti dell'altro gruppo. Nel caso di questo codice che usa unit()
, se ti interessa davvero cosa succede in un caso di divisione per 0, dovresti aver scritto tu stesso il test. Quindi, se lo sposti su un sistema embedded, dove ottieni solo risultati cattivi, quel comportamento è "sano di mente". Ora, dal punto di vista del business, alleno una volta i miei programmatori e utilizzano le stesse API e gli stessi stili in tutte le parti della mia attività.
Nella grande maggioranza dei casi, si desidera seguire il consiglio degli altri: usare idiomi come tryGetUnit()
o simili per le funzioni che non generano eccezioni e restituiscono invece un valore sentinella come null. Se ritieni che gli utenti possano voler utilizzare sia la gestione delle eccezioni sia il codice di gestione senza eccezioni affiancati all'interno di un singolo programma, segui la notazione tryGetUnit()
. Tuttavia, esiste un caso limite in cui la realtà aziendale può rendere migliore l'uso di una bandiera. Se ti trovi in quel caso d'angolo, non aver paura di gettare le "regole" sul ciglio della strada. Ecco a cosa servono le regole!