1. งานของโปรแกรมเมอร์

บ่อยครั้งที่โปรแกรมเมอร์มือใหม่คิดว่างานของโปรแกรมเมอร์แตกต่างไปจากที่โปรแกรมเมอร์ที่มีประสบการณ์คิด

ผู้เริ่มต้นมักจะพูดว่า "โปรแกรมใช้งานได้ คุณต้องการอะไรอีก" โปรแกรมเมอร์ที่มีประสบการณ์รู้ดีว่า "การทำงานอย่างถูกต้อง" เป็นเพียงหนึ่งในข้อกำหนดสำหรับโปรแกรมและไม่ใช่สิ่งที่สำคัญที่สุดด้วยซ้ำ !

อ่านโค้ดได้

สิ่งที่สำคัญที่สุดคือโปรแกรมเมอร์คนอื่นสามารถเข้าใจรหัสโปรแกรมได้ สิ่งนี้สำคัญกว่าโปรแกรมที่ทำงานได้อย่างถูกต้อง ล้นหลาม.

หากคุณมีโปรแกรมที่ทำงานไม่ถูกต้อง คุณสามารถแก้ไขได้ แต่ถ้าคุณมีโปรแกรมที่รหัสไม่สามารถเข้าใจได้ คุณจะไม่สามารถทำอะไรกับมันได้

เพียงใช้โปรแกรมที่คอมไพล์แล้ว เช่น notepad และเปลี่ยนสีพื้นหลังเป็นสีแดง คุณมีโปรแกรมที่ใช้งานได้ แต่คุณไม่มีซอร์สโค้ดที่เข้าใจได้: เป็นไปไม่ได้ที่จะเปลี่ยนแปลงโปรแกรมเช่นนั้น

ตัวอย่างตำราคือเมื่อนักพัฒนา Microsoft ลบเกม Pinball ออกจาก Windows เนื่องจากไม่สามารถพอร์ตไปยังสถาปัตยกรรม 64 บิตได้ และพวกเขายังมีซอร์สโค้ดด้วย พวกเขา ไม่เข้าใจวิธีการ ทำงานของโค้ด

บัญชีสำหรับทุกกรณีการใช้งาน

ข้อกำหนดที่สำคัญอันดับสองสำหรับโปรแกรมคือการคำนึงถึงทุกสถานการณ์ บ่อยครั้งที่สิ่งต่าง ๆ ซับซ้อนกว่าที่คิดเล็กน้อย

โปรแกรมเมอร์มือใหม่มองเห็นการส่งข้อความ SMS อย่างไร:

โปรแกรมทำงานอย่างถูกต้อง

โปรแกรมเมอร์มืออาชีพมองอย่างไร:

โปรแกรมทำงานอย่างถูกต้อง

สถานการณ์ "ทำงานอย่างถูกต้อง" มักจะเป็นไปได้เพียงหนึ่งเดียว และนั่นคือสาเหตุที่มือใหม่หลายคนบ่นเกี่ยวกับตัวตรวจสอบความถูกต้องของงาน CodeGym: มีเพียงสถานการณ์เดียวจาก 10 เหตุการณ์เท่านั้นที่ใช้งานได้ และโปรแกรมเมอร์มือใหม่ก็คิดว่าเพียงพอแล้ว


2. สถานการณ์ไม่ปกติ

สถานการณ์ไม่ปกติ

สถานการณ์ผิดปกติอาจเกิดขึ้นในการดำเนินการของโปรแกรมใดๆ

ตัวอย่างเช่น คุณตัดสินใจที่จะบันทึกไฟล์ แต่ไม่มีพื้นที่ดิสก์ หรือโปรแกรมพยายามเขียนข้อมูลลงในหน่วยความจำ แต่หน่วยความจำที่มีอยู่เหลือน้อย หรือคุณดาวน์โหลดรูปภาพจากอินเทอร์เน็ต แต่การเชื่อมต่อขาดหายระหว่างกระบวนการดาวน์โหลด

สำหรับแต่ละสถานการณ์ที่ผิดปกติ โปรแกรมเมอร์ (ผู้เขียนโปรแกรม) ต้อง a) คาดการณ์ล่วงหน้า b) ตัดสินใจว่าโปรแกรมควรจัดการกับมันอย่างไรและ c) เขียนวิธีแก้ปัญหาที่ใกล้เคียงกับที่ต้องการมากที่สุด

นั่นเป็นสาเหตุที่โปรแกรมมีพฤติกรรมง่ายๆ มาเป็นเวลานาน: หากเกิดข้อผิดพลาดในโปรแกรม โปรแกรมจะหยุดทำงาน และนั่นเป็นวิธีที่ค่อนข้างดี

สมมติว่าคุณต้องการบันทึกเอกสารลงดิสก์ ในระหว่างกระบวนการบันทึก คุณพบว่าพื้นที่ดิสก์ไม่เพียงพอ พฤติกรรมใดที่คุณต้องการมากที่สุด:

  • โปรแกรมสิ้นสุดลง
  • โปรแกรมยังคงทำงานต่อไป แต่ไม่บันทึกไฟล์

โปรแกรมเมอร์มือใหม่อาจคิดว่าตัวเลือกที่สองนั้นดีกว่า เนื่องจากโปรแกรมยังคงทำงานอยู่ แต่ในความเป็นจริงไม่เป็นเช่นนั้น

ลองนึกภาพว่าคุณพิมพ์เอกสารใน Word เป็นเวลา 3 ชั่วโมง แต่สองนาทีในกระบวนการเขียนของคุณ เห็นได้ชัดว่าโปรแกรมจะไม่สามารถบันทึกเอกสารลงในดิสก์ได้ ดีกว่าที่จะสูญเสียงานสองนาทีหรือสามชั่วโมง?

หากโปรแกรมไม่สามารถทำในสิ่งที่ต้องการได้ จะดีกว่าที่จะปล่อยให้ปิดไป ดีกว่าแสร้งทำเป็นว่าทุกอย่างเรียบร้อยดี สิ่งที่ดีที่สุดที่โปรแกรมสามารถทำได้เมื่อพบข้อผิดพลาดที่ไม่สามารถแก้ไขได้ด้วยตัวของมันเอง คือการรายงานปัญหาให้ผู้ใช้ทราบทันที


3. ความเป็นมาเกี่ยวกับข้อยกเว้น

ไม่ใช่โปรแกรมเดียวที่เผชิญกับสถานการณ์ที่ผิดปกติ นอกจากนี้ยังเกิดขึ้นภายในโปรแกรม — ในวิธีการ ตัวอย่างเช่น:

  • เมธอดต้องการเขียนไฟล์ลงดิสก์ แต่ไม่มีที่ว่าง
  • เมธอดต้องการเรียกใช้ฟังก์ชันบนตัวแปร แต่ตัวแปรมีค่าเท่ากับ null
  • การหารด้วย 0 เกิดขึ้นในเมธอด

ในกรณีนี้ เมธอดการโทรอาจแก้ไขสถานการณ์ได้ (ดำเนินการสถานการณ์ทางเลือก) หากรู้ว่าปัญหาประเภทใดเกิดขึ้นในเมธอดที่เรียก

หากเราพยายามบันทึกไฟล์ลงในดิสก์และมีไฟล์ดังกล่าวอยู่แล้ว เราสามารถขอให้ผู้ใช้ยืนยันว่าเราควรเขียนทับไฟล์ หากไม่มีพื้นที่ว่างในดิสก์ เราสามารถแสดงข้อความถึงผู้ใช้และขอให้ผู้ใช้เลือกดิสก์อื่น แต่ถ้าโปรแกรมมีหน่วยความจำไม่เพียงพอโปรแกรมก็จะหยุดทำงาน

กาลครั้งหนึ่งนานมาแล้ว โปรแกรมเมอร์ได้ครุ่นคิดถึงคำถามนี้และพบวิธีแก้ปัญหาดังต่อไปนี้: เมธอด/ฟังก์ชันทั้งหมดจะต้องส่งคืนรหัสข้อผิดพลาดที่ระบุผลลัพธ์ของการดำเนินการ หากฟังก์ชันทำงานได้อย่างสมบูรณ์ มันจะคืนค่า0 หากไม่เป็นเช่นนั้น ระบบจะส่งคืนรหัสข้อผิดพลาด (ไม่ใช่ศูนย์)

ด้วยวิธีการนี้เพื่อแก้ไขข้อผิดพลาด หลังจากการเรียกใช้ฟังก์ชันเกือบทุกครั้ง โปรแกรมเมอร์ต้องเพิ่มการตรวจสอบเพื่อดูว่าฟังก์ชันเสร็จสิ้นโดยมีข้อผิดพลาดหรือไม่ รหัสบอลลูนมีขนาดและมีลักษณะดังนี้:

รหัสโดยไม่มีการจัดการข้อผิดพลาด รหัสที่มีการจัดการข้อผิดพลาด
File file = new File("ca:\\note.txt");
file.writeLine("Text");
file.close();
File file = new File("ca:\\note.txt");
int status = file.writeLine("Text");
if (status == 1)
{
   ...
}
else if (status == 2)
{
   ...
}
status = file.close();
if (status == 3)
{
   ...
}

ยิ่งไปกว่านั้น บ่อยครั้งที่ฟังก์ชันที่พบว่ามีข้อผิดพลาดเกิดขึ้นโดยไม่รู้ว่าต้องทำอย่างไร: ผู้โทรต้องส่งคืนข้อผิดพลาด และผู้โทรของผู้โทรส่งคืนข้อผิดพลาดไปยังผู้โทร และอื่น ๆ

ในโปรแกรมขนาดใหญ่ การเรียกใช้ฟังก์ชันต่อเนื่องกันนับสิบครั้งถือเป็นบรรทัดฐาน บางครั้งคุณอาจพบความลึกของการโทรเป็นร้อยๆ ฟังก์ชันด้วยซ้ำ และตอนนี้คุณต้องส่งรหัสข้อผิดพลาดจากด้านล่างสุดไปด้านบนสุด และหากบางฟังก์ชันไม่จัดการรหัสทางออกข้อผิดพลาดจะหายไป

ข้อเสียอีกประการของแนวทางนี้คือ หากฟังก์ชันส่งคืนรหัสข้อผิดพลาด จะไม่สามารถส่งคืนผลลัพธ์ของงานของตนเองได้อีกต่อไป ผลลัพธ์ของการคำนวณจะต้องส่งผ่านพารามิเตอร์อ้างอิง สิ่งนี้ทำให้โค้ดยุ่งยากมากขึ้นและเพิ่มจำนวนข้อผิดพลาดมากขึ้น