หลักฐาน
รหัสต่อไปนี้ควรถือเป็นรูปแบบที่ไม่ดีโดยไม่คำนึงถึงภาษาหรือฟังก์ชันที่ต้องการ:
while( true ) {
}
สนับสนุนอาร์กิวเมนต์
การwhile( true )
วนซ้ำเป็นรูปแบบที่ไม่ดีเนื่องจาก:
- ทำลายสัญญาโดยนัยของ while loop
- ประกาศในขณะที่ห่วงอย่างชัดเจนควรระบุเพียงเงื่อนไขทางออก
- หมายความว่ามันวนซ้ำตลอดไป
- ต้องอ่านรหัสภายในลูปเพื่อทำความเข้าใจกับประโยคยุติ
- ลูปที่ทำซ้ำตลอดไปจะป้องกันไม่ให้ผู้ใช้ยุติโปรแกรมจากภายในโปรแกรม
- ไม่มีประสิทธิภาพ
- มีเงื่อนไขการสิ้นสุดลูปหลายเงื่อนไขรวมถึงการตรวจสอบ "จริง"
- มีแนวโน้มที่จะเกิดข้อบกพร่อง
- ไม่สามารถระบุได้อย่างง่ายดายว่าจะวางโค้ดไว้ที่ใดซึ่งจะรันสำหรับการวนซ้ำแต่ละครั้ง
- นำไปสู่รหัสที่ซับซ้อนโดยไม่จำเป็น
- การวิเคราะห์ซอร์สโค้ดอัตโนมัติ
- หากต้องการค้นหาจุดบกพร่องการวิเคราะห์ความซับซ้อนของโปรแกรมการตรวจสอบความปลอดภัยหรือหาลักษณะการทำงานของซอร์สโค้ดอื่น ๆ โดยอัตโนมัติโดยไม่มีการเรียกใช้โค้ดการระบุเงื่อนไขการทำลายเริ่มต้นช่วยให้อัลกอริทึมสามารถกำหนดค่าคงที่ที่เป็นประโยชน์ได้ซึ่งจะช่วยปรับปรุงเมตริกการวิเคราะห์ซอร์สโค้ดอัตโนมัติ
- ลูปไม่มีที่สิ้นสุด
- หากทุกคนมักใช้
while(true)
สำหรับลูปที่ไม่สิ้นสุดเราจะสูญเสียความสามารถในการสื่อสารอย่างรัดกุมเมื่อลูปไม่มีเงื่อนไขยุติ (เป็นเรื่องที่เกิดขึ้นแล้วดังนั้นประเด็นคือการสงสัย)
ทางเลือกสำหรับ "ไปที่"
รหัสต่อไปนี้เป็นรูปแบบที่ดีกว่า:
while( isValidState() ) {
execute();
}
bool isValidState() {
return msg->state != DONE;
}
ข้อดี
ไม่มีธง. goto
ไม่ ไม่มีข้อยกเว้น. ง่ายต่อการเปลี่ยนแปลง อ่านง่าย แก้ไขได้ง่าย. นอกจากนี้รหัส:
- แยกความรู้เกี่ยวกับภาระงานของลูปออกจากลูปเอง
- ช่วยให้ผู้ที่ดูแลรหัสสามารถขยายฟังก์ชันการทำงานได้อย่างง่ายดาย
- อนุญาตให้กำหนดเงื่อนไขการยกเลิกได้หลายรายการในที่เดียว
- แยกส่วนคำสั่งยุติออกจากโค้ดเพื่อดำเนินการ
- ปลอดภัยกว่าสำหรับโรงไฟฟ้านิวเคลียร์ ;-)
จุดที่สองมีความสำคัญ โดยไม่ทราบว่าโค้ดทำงานอย่างไรหากมีคนขอให้ฉันสร้างลูปหลักให้เธรดอื่น ๆ (หรือกระบวนการ) มีเวลา CPU อยู่บ้างก็ควรคำนึงถึงสองวิธี:
ตัวเลือกที่ 1
แทรกการหยุดชั่วคราวได้ทันที:
while( isValidState() ) {
execute();
sleep();
}
ตัวเลือก # 2
แทนที่ดำเนินการ:
void execute() {
super->execute();
sleep();
}
รหัสนี้จะง่าย (จึงง่ายต่อการอ่าน) switch
กว่าวงที่มีการฝังตัว isValidState
วิธีเดียวที่ควรตรวจสอบว่าวงที่ควรดำเนินการต่อ เวิร์กฮอร์สของเมธอดควรถูกสรุปลงในexecute
เมธอดซึ่งอนุญาตให้คลาสย่อยสามารถแทนที่พฤติกรรมเริ่มต้นได้ (งานที่ยากโดยใช้การฝังswitch
และgoto
)
ตัวอย่าง Python
เปรียบเทียบคำตอบต่อไปนี้ (สำหรับคำถาม Python) ที่โพสต์บน StackOverflow:
- วนลูปตลอดไป.
- ขอให้ผู้ใช้ป้อนตัวเลือก
- หากอินพุตของผู้ใช้คือ "รีสตาร์ท" ให้วนลูปต่อไปตลอดกาล
- มิฉะนั้นจะหยุดการวนซ้ำตลอดไป
- ปลาย
รหัส
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
เมื่อเทียบกับ:
- เริ่มต้นตัวเลือกของผู้ใช้
- วนซ้ำในขณะที่ตัวเลือกของผู้ใช้คือคำว่า 'เริ่มต้นใหม่'
- ขอให้ผู้ใช้ป้อนตัวเลือก
- ปลาย
รหัส
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
ซึ่งจะwhile True
ส่งผลให้เกิดรหัสที่ทำให้เข้าใจผิดและซับซ้อนเกินไป