Considere el siguiente código:
public void doSomething(int input)
{
while(true)
{
TransformInSomeWay(input);
if(ProcessingComplete(input))
break;
DoSomethingElseTo(input);
}
}
Suponga que este proceso implica un número finito pero dependiente de entrada de pasos; el bucle está diseñado para terminar por sí solo como resultado del algoritmo, y no está diseñado para ejecutarse indefinidamente (hasta que sea cancelado por un evento externo). Debido a que la prueba para ver si el ciclo debe finalizar se encuentra en el medio de un conjunto lógico de pasos, el ciclo while en sí mismo actualmente no verifica nada significativo; la verificación se realiza en el lugar "apropiado" dentro del algoritmo conceptual.
Me dijeron que este es un código incorrecto, porque es más propenso a errores debido a que la estructura de bucle no verifica la condición de finalización. Es más difícil descubrir cómo saldría del bucle, y podría invitar a los errores, ya que la condición de ruptura podría omitirse u omitirse accidentalmente en futuros cambios.
Ahora, el código podría estructurarse de la siguiente manera:
public void doSomething(int input)
{
TransformInSomeWay(input);
while(!ProcessingComplete(input))
{
DoSomethingElseTo(input);
TransformInSomeWay(input);
}
}
Sin embargo, esto duplica una llamada a un método en código, violando DRY; si TransformInSomeWay
luego se reemplazara con algún otro método, ambas llamadas tendrían que ser encontradas y cambiadas (y el hecho de que haya dos puede ser menos obvio en un código más complejo).
También puedes escribirlo como:
public void doSomething(int input)
{
var complete = false;
while(!complete)
{
TransformInSomeWay(input);
complete = ProcessingComplete(input);
if(!complete)
{
DoSomethingElseTo(input);
}
}
}
... pero ahora tiene una variable cuyo único propósito es cambiar la verificación de condición a la estructura de bucle, y también debe verificarse varias veces para proporcionar el mismo comportamiento que la lógica original.
Por mi parte, digo que dado el algoritmo que este código implementa en el mundo real, el código original es el más legible. Si lo estuviera haciendo usted mismo, esta es la forma en que lo pensaría, por lo que sería intuitivo para las personas familiarizadas con el algoritmo.
Entonces, ¿cuál es "mejor"? ¿Es mejor dar la responsabilidad de la verificación de condiciones al ciclo while estructurando la lógica alrededor del ciclo? ¿O es mejor estructurar la lógica de una manera "natural" como lo indican los requisitos o una descripción conceptual del algoritmo, aunque eso puede significar pasar por alto las capacidades integradas del bucle?
do ... until
construcción también es útil para este tipo de bucles ya que no tienen que estar "cebados".