Come smettere di scrivere il codice a catena?
-
28-09-2019 - |
Domanda
per esempio ...
if ( /* Condition */ ) {
if ( /* Condition */ ) {
if ( /* Condition */ ) {
// Superb!
} else {
// Error 3
}
} else {
// Error 2
}
} else {
// Error 1
}
Sai come evitare questo? Grazie!
Soluzione
Se questa è una funzione di libreria, throw
può essere l'azione appropriata.
if (!condition1) {
throw "Condition 1 failed.";
}
if (!condition2) {
throw "Condition 2 failed.";
}
if (!condition3) {
throw "Condition 3 failed.";
}
// Superb!
Altre azioni accettabili potrebbero essere:
- Tornando
0
,null
oundefined
. - Visualizzazione di un errore per l'utente e il ritorno.
Si dovrà determinare quale azione fallimento è giusto per il vostro caso d'uso.
Altri suggerimenti
Sembra che avete 3 condizioni di controllare e 4 azioni (3 diversi errori di + 1 di successo). Purtroppo nel caso generale è andare a richiedere 3 controlli condizionali e 4 azioni. Credo che il codice può essere ripulito un po 'utilizzando la seguente struttura anche se
if (! /* condition 1 */ ) {
// Error 1
} else if (! /* condition 2 */ ) {
// Error 2
} else if (! /* condition 3 */ ) {
// Error 3
} else {
// superb
}
Si può usare le eccezioni, o si rompe all'interno di un blocco, o di funzioni multiple. Spesso questo richiede invertendo le vostre condizioni per ottenere il codice ordinato nel modo giusto.
do {
if (! /* Condition 1 */ ) {
// Error 1
break;
}
if (! /* Condition 2 */ ) {
// Error 2
break;
}
if (! /* Condition 3 */ ) {
// Error 3
break;
}
// Superb!
} while (false);
Il do-while (false) loop è un modo di fare un blocco che si può uscire da in lingue che non tollererà un blocco anonimo. Si potrebbe facilmente essere una funzione e utilizzare i rendimenti, o un try-catch con le eccezioni.
Si preferisce questo?
if ( /* Condition 1*/ && /* Condition 2*/ && /* Condition 3 */) {
// Superb!
}
else if (! /* Condition 1*/){
// Error 1
}
else if (! /* Condition 2*/){
// Error 2
}
else if (! /* Condition 3*/){
// Error 3
}
if ( ! /* Condition */ ) {
Error 1
throw someSortOfException
}
if (! condition 2){
Error 2
throw someSortOfOtherException
}
if (! condition 3){
Error 3
throw another Exception
}
// Success!
A seconda della situazione, il codice può essere preferito. Probabilmente si vorrà per la cattura di tali eccezioni da qualche parte, per esempio.
if (!condition1)
// Error 1 (and exit scope if necessary)
if (!condition2)
// Error 2 (and exit scope if necessary)
if (!condition3)
// Error 3 (and exit scope if necessary)
// Superb!
Sì; è possibile comporre insieme le sue dichiarazioni if
in una singola istruzione composta utilizzando l'operatore, e gestire le condizioni di errore in un unico blocco. A seconda della gestione esigenze errore, però, potrebbe essere necessario avere di nuovo più if
s per assicurarsi che si sta adeguatamente gestire l'errore (dipende dalla vostra gestione risoluzione errori, in realtà).
Vale a dire:
if (CondA && CondB && CondC)
{
// Execute success
}
else
{
if (!CondA)
// Do error A
else if (!CondB)
// Do error B
else if (!CondC)
// Do error C
}
}
Ci sono alcuni modi, il più semplice è di busto semplicemente fuori alcune funzioni e astratta i diversi strati (questo dovrebbe essere fatto in ogni caso se vi trovate andando in profondità.)
if ( /* Condition */ ) {
value = aFunctionSaysWhat();
} else {
// value = Error 1
}
....
value aFunctionSaysWhat(){
if ( /* Condition */ ) {
return aSecondFunctionHere();
} else {
// return Error 2
}
}
La premessa fondamentale è che una funzione deve vivere su un livello di astrazione, se possibile, e fare una cosa.
La prossima possibilità è di appiattire tutto fuori, questo è superiore al metodo annidato iniziale, ma ha sostanzialmente analoga complessità. Potrebbe essere molto più pulito di quanto l'approccio funzionale, se avete solo un paio di opzioni e non si ha intenzione di aggiungere altro.
if(ErrorCondition1){
//Error 1
}else if(ErrorCondition2){
//Error 2
}else if(ErrorCondition3){
//Error 3
}else{
//Superb
}
Infine, è possibile memorizzare un hash o mappa con le risposte desiderate e rimuovere il caso del tutto, la capacità di implementare questo si basa sulla sua capacità di hash qualche risultato:
Results = {'Result1':'Error1', 'Result2':'Error2', 'Result3':'Error3', 'Success':'Superb'}
return Results[ConditionHash(Condition)];