Pertimbangkan kode berikut:
public void doSomething(int input)
{
while(true)
{
TransformInSomeWay(input);
if(ProcessingComplete(input))
break;
DoSomethingElseTo(input);
}
}
Asumsikan bahwa proses ini melibatkan sejumlah langkah yang terbatas tetapi bergantung pada input; loop dirancang untuk berakhir dengan sendirinya sebagai akibat dari algoritma, dan tidak dirancang untuk berjalan tanpa batas waktu (sampai dibatalkan oleh peristiwa luar). Karena tes untuk melihat apakah loop harus diakhiri berada di tengah serangkaian langkah logis, loop sementara itu sendiri saat ini tidak memeriksa sesuatu yang berarti; Sebaliknya cek dilakukan di tempat "layak" dalam algoritma konseptual.
Saya diberitahu bahwa ini adalah kode yang buruk, karena lebih rentan terhadap bug karena kondisi akhir tidak diperiksa oleh struktur loop. Lebih sulit untuk mengetahui bagaimana Anda keluar dari loop, dan dapat mengundang bug karena kondisi kerusakan mungkin dilewati atau dihilangkan secara tidak sengaja karena perubahan di masa mendatang.
Sekarang, kode dapat disusun sebagai berikut:
public void doSomething(int input)
{
TransformInSomeWay(input);
while(!ProcessingComplete(input))
{
DoSomethingElseTo(input);
TransformInSomeWay(input);
}
}
Namun, ini menggandakan panggilan ke metode dalam kode, melanggar KERING; jika TransformInSomeWay
kemudian diganti dengan metode lain, kedua panggilan harus ditemukan dan diubah (dan fakta bahwa ada dua mungkin kurang jelas dalam potongan kode yang lebih kompleks).
Anda juga bisa menulis seperti:
public void doSomething(int input)
{
var complete = false;
while(!complete)
{
TransformInSomeWay(input);
complete = ProcessingComplete(input);
if(!complete)
{
DoSomethingElseTo(input);
}
}
}
... tetapi Anda sekarang memiliki variabel yang hanya bertujuan untuk mengubah kondisi-memeriksa ke struktur lingkaran, dan juga harus diperiksa beberapa kali untuk memberikan perilaku yang sama dengan logika asli.
Bagi saya, saya katakan bahwa dengan algoritma yang diterapkan kode ini di dunia nyata, kode asli adalah yang paling mudah dibaca. Jika Anda mengalaminya sendiri, ini adalah cara Anda akan memikirkannya, dan itu akan menjadi intuitif bagi orang-orang yang terbiasa dengan algoritma.
Jadi, mana yang "lebih baik"? Apakah lebih baik memberikan tanggung jawab memeriksa kondisi ke loop sementara dengan menyusun logika di sekitar loop? Atau lebih baik untuk menyusun logika dengan cara "alami" seperti yang ditunjukkan oleh persyaratan atau deskripsi konseptual dari algoritma, meskipun itu mungkin berarti melewati kemampuan bawaan loop?
do ... until
membangun juga berguna untuk jenis-jenis loop karena mereka tidak harus "prima."