Che cos'è un buon modello di codice per singolo tentativo quindi errore?

5

Sto scrivendo una routine che ha la seguente forma:

TRY A
IF no success, B
IF no success, RETRY A
IF no success, throw error

Non è banale estrarre A o B nella propria routine, quindi qual è la struttura più semplice che mi permetterà di riprovare A senza duplicazione del codice?

Attualmente, ho un do..while che consente di ritentare N :

int retries = 1;

do {
    // DO A

    if ( /*success*/ ) {
        break;
    } else if (retries > 0)  {
        // DO B

        if ( /*success*/) {
            break;
        }
    } else {
        // throw Error
    }
} while (retries-- > 0);

Questo è brutto e non ideale in quanto implica che potrei voler riprovare più volte, cosa che non voglio. Dovrò usare un ciclo, ma ci deve essere un modo più semplice che non vedo.

Per contesto, questo è il codice generato in Java, eseguendo istruzioni SQL per provare prima un UPDATE , quindi se non viene trovata nessuna voce per l'aggiornamento, INSERT , e se quel comando fallisce (concorrenza, già creato), prova UPDATE di nuovo.

    
posta Nicole 07.12.2011 - 02:53
fonte

2 risposte

9

Ho scritto questo in C, quindi non posso garantire che verrà tagliato e incollato in Java.

Se sei sicuro di voler riprovare DoA una volta sola, puoi usare una sola riga:

bool DoIt()
{
    return DoA() || DoB() || DoA();
}

bool DoA() { } // Return true if successful.

bool DoB() { } // Return true if successful.

Se vuoi l'opzione di più di un tentativo, usa questo ciclo.

bool DoIt(int retryLimit)
{
    if (DoA()) return true;
    for (int retries = 0; retries < retryLimit; retries++)
    {
        if (DoB()) return true;
        if (DoA()) return true;
    }
    return false;
}

Modifica: se davvero non puoi guadagnare tempo per estrarre DoA e DoB , quindi prova il seguente blocco. Ricorda che i commenti sono tuoi amici:

bool retry = false;
bool success = false;
do
{
    // Do A.
    success = // true or false
    if (success) break;

    // Attempt the above code twice and the below code once.
    if (retrying) break;
    retrying = true;

    // Do B.
    success = // true or false
    if (success) break;
}
if (success)
{
    // Celebrate.
}
else
{
    // Commiserate.
}
    
risposta data 07.12.2011 - 03:29
fonte
2

Perché non esegui una selezione per verificare se la riga esiste, al contrario di una versione aggiornata con un test di errore?

Quindi puoi semplicemente inserire o aggiornare ...

    
risposta data 07.12.2011 - 03:01
fonte

Leggi altre domande sui tag