Considera il seguente codice:
public void doSomething(int input)
{
while(true)
{
TransformInSomeWay(input);
if(ProcessingComplete(input))
break;
DoSomethingElseTo(input);
}
}
Supponiamo che questo processo implichi un numero limitato di passaggi, dipendenti dall'input; il ciclo è progettato per terminare da solo come risultato dell'algoritmo e non è progettato per funzionare indefinitamente (finché non viene annullato da un evento esterno). Poiché il test per vedere se il ciclo deve terminare è nel mezzo di una serie logica di passaggi, il ciclo while non controlla attualmente nulla di significativo; il controllo viene invece eseguito nella posizione "corretta" all'interno dell'algoritmo concettuale.
Mi è stato detto che questo è un codice errato, perché è più soggetto a bug a causa della condizione di fine non controllata dalla struttura del ciclo. È più difficile capire come uscire dal ciclo e potrebbe invitare bug in quanto la condizione di rottura potrebbe essere ignorata o omessa in caso di modifiche future.
Ora il codice potrebbe essere strutturato come segue:
public void doSomething(int input)
{
TransformInSomeWay(input);
while(!ProcessingComplete(input))
{
DoSomethingElseTo(input);
TransformInSomeWay(input);
}
}
Tuttavia, questo duplica una chiamata a un metodo nel codice, violando DRY; se TransformInSomeWay
è stato successivamente sostituito con qualche altro metodo, entrambe le chiamate dovrebbero essere trovate e modificate (e il fatto che ce ne siano due potrebbe essere meno ovvio in una parte di codice più complessa).
Potresti anche scrivere come:
public void doSomething(int input)
{
var complete = false;
while(!complete)
{
TransformInSomeWay(input);
complete = ProcessingComplete(input);
if(!complete)
{
DoSomethingElseTo(input);
}
}
}
... ma ora disponi di una variabile il cui unico scopo è spostare il controllo delle condizioni nella struttura del ciclo e deve essere controllato più volte per fornire lo stesso comportamento della logica originale.
Per parte mia, dico che dato l'algoritmo che questo codice implementa nel mondo reale, il codice originale è il più leggibile. Se lo stessi facendo tu, questo è il modo in cui ci penserai e quindi sarebbe intuitivo che le persone abbiano familiarità con l'algoritmo.
Quindi, che è "migliore"? è meglio dare la responsabilità del controllo delle condizioni al ciclo while strutturando la logica attorno al ciclo? O è meglio strutturare la logica in un modo "naturale" come indicato dai requisiti o una descrizione concettuale dell'algoritmo, anche se ciò potrebbe significare ignorare le capacità integrate del ciclo?