Ci sono cose buone da dire sull'avere un unico punto di uscita, così come ci sono cose cattive da dire sull'inevitabile programmazione a "freccia" che ne risulta.
Se utilizzo più punti di uscita durante la convalida dell'input o l'allocazione delle risorse, provo a mettere tutte le "uscite di errore" in modo molto visibile in cima alla funzione.
Sia l' articolo di programmazione spartana di "SSDSLPedia" sia il punto di uscita a singola funzione articolo del del "Wiki del Portland Pattern Repository" hanno alcuni argomenti approfonditi al riguardo. Inoltre, ovviamente, c'è questo post da considerare.
Se vuoi davvero un singolo punto di uscita (in qualsiasi linguaggio non abilitato alle eccezioni), ad esempio per liberare risorse in un unico posto, trovo che l'applicazione attenta di goto sia buona; vedi ad esempio questo esempio piuttosto forzato (compresso per salvare lo schermo immobiliare):
int f(int y) {
int value = -1;
void *data = NULL;
if (y < 0)
goto clean;
if ((data = malloc(123)) == NULL)
goto clean;
/* More code */
value = 1;
clean:
free(data);
return value;
}
Personalmente, in generale, non mi piace la programmazione delle frecce più di quanto non mi piacciano più punti di uscita, sebbene entrambi siano utili se applicati correttamente. Il migliore, ovviamente, è strutturare il programma in modo da non richiedere nessuno dei due. Abbattere la funzione in più blocchi di solito aiuta :)
Anche se, facendo ciò, trovo che alla fine con più punti di uscita, come in questo esempio, in cui alcune funzioni più grandi sono state suddivise in diverse funzioni più piccole:
int g(int y) {
value = 0;
if ((value = g0(y, value)) == -1)
return -1;
if ((value = g1(y, value)) == -1)
return -1;
return g2(y, value);
}
A seconda del progetto o delle linee guida di codifica, la maggior parte del codice della piastra della caldaia potrebbe essere sostituito da macro. Come nota a margine, scomporlo in questo modo rende le funzioni g0, g1, g2 molto facili da testare individualmente.
Ovviamente, in un linguaggio OO e abilitato per le eccezioni, non userei istruzioni if del genere (o del tutto, se potessi cavarmela con il minimo sforzo), e il codice sarebbe molto più semplice. E non frizzante. E la maggior parte dei rendimenti non finali sarebbero probabilmente eccezioni.
In breve;
- Pochi ritorni sono migliori di molti ritorni
- Più di un ritorno è meglio di enormi frecce e le clausole di guardia sono generalmente ok.
- Le eccezioni potrebbero / dovrebbero probabilmente sostituire la maggior parte delle "clausole di guardia" quando possibile.