ข้อยกเว้น“ ข้อผิดพลาดในการเขียนโปรแกรม” - แนวทางของฉันมีเสียงดีหรือไม่?


9

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

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


ฉันมักจะแยกแยะข้อยกเว้นประเภทอื่น: ข้อยกเว้นทางธุรกิจ อ้างถึงเงื่อนไขข้อผิดพลาดที่ผู้ใช้สนใจในรายละเอียดของ ฉันมักจะทำการตรวจสอบข้อยกเว้นเหล่านั้น
beluchin

คำตอบ:


2

ฉันคิดว่าคุณกำลังอยู่ในเส้นทางที่ถูกต้อง การขว้างปาจับหรือจัดทำเอกสารข้อยกเว้นที่อาจเกิดขึ้นได้ทั้งหมดไม่สมเหตุสมผลนัก มีหลายครั้งที่ความเข้มงวดของผลิตภัณฑ์ต้องการระดับที่สูงขึ้นของการจ้างงานและการจัดทำเอกสารยกเว้น (เช่นลักษณะที่สำคัญด้านความปลอดภัยของระบบ)

กลยุทธ์ของการป้องกันมากขึ้นโดยใช้แนวคิดสัญญาเพื่อระบุเงื่อนไข (และ postconditions) โดยเฉพาะอย่างยิ่งผู้โทรดาวน์สตรีม (เช่นสิ่งใดก็ตามที่มีลักษณะคล้ายกับสมาชิกสาธารณะหรือสมาชิกที่ได้รับความคุ้มครอง) มักจะมีประสิทธิภาพและยืดหยุ่นมากขึ้น สิ่งนี้ไม่เพียงนำไปใช้กับการนำไปใช้ แต่ยังรวมถึงเอกสารประกอบ หากนักพัฒนาทราบว่าสิ่งที่คาดหวังพวกเขามีแนวโน้มที่จะปฏิบัติตามกฎระเบียบและมีแนวโน้มที่จะสับสนน้อยลงหรือใช้รหัสที่คุณเขียนในทางที่ผิด

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

สำหรับพารามิเตอร์ที่ไม่ใช่ null ในฐานะผู้บริโภคของสมาชิกสาธารณะหรือสมาชิกที่ได้รับการปกป้องฉันต้องการทราบว่าไม่อนุญาต ฉันต้องการทราบว่าช่วงของค่าที่ถูกต้องในบริบทที่กำหนดคืออะไร ฉันต้องการทราบผลที่ตามมาของการใช้ค่าที่อยู่นอกช่วงปกติ แต่ไม่ถูกต้องในบริบทการโทรที่แตกต่างกัน (เช่นค่าของประเภทนั้นโดยทั่วไปถูกต้องสำหรับการดำเนินการใด ๆ แต่ไม่ใช่ที่นี่ - เช่นพารามิเตอร์บูลีนที่ไม่ ไม่คาดหวังความผิดพลาดเป็นค่าที่ถูกต้อง

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

โดยเฉพาะกับ IDisposable มักจะใช้งานอินเทอร์เฟซนี้เสนอวิธีการอื่นที่ต้องการผ่านกระบวนการกำจัดอย่างชัดเจน ในกรณีเหล่านี้ให้ไฮไลต์วิธีที่ต้องการและโปรดทราบว่าไม่ต้องการการกำจัดที่ชัดเจน


ฉันเข้าใจถึงความจำเป็นในการจัดทำเอกสารซึ่งอนุญาตให้ใช้ค่าใด แต่ถ้าคุณเห็นฟังก์ชันperformReadCommand(ICommand cmd, int replySizeBytes)- คุณคาดหวังหรือไม่ว่า null จะยอมรับได้สำหรับ cmd หรือค่าลบสำหรับ replySizeBytes เอกสาร IMO จะจำเป็นเฉพาะเมื่อค่าเหล่านั้นได้รับอนุญาตจริงและคุณควรระบุว่า 0 นั้นถูกต้องสำหรับ replySizeBytes
Medo42

พวกเขาทั้งสองอาจ "ถูกต้อง" ขึ้นอยู่กับการใช้งาน คุณเป็นหรือฉันและทุกคนที่นี่แม้จะไม่คาดหวังว่าค่า Null หรือค่าลบจะเหมาะสมสำหรับลายเซ็นนั้น แต่ก็อาจเป็นได้ พิจารณาสภาพแวดล้อมที่ผู้อ่านกำลังบล็อกกระบวนการคงอยู่และเมื่อ cmd เป็นโมฆะอาจหมายถึงการไม่เปลี่ยนคำสั่งที่ใช้โดยตัวอ่านและดำเนินการอ่านครั้งต่อไปโดยใช้คำสั่ง previious ในกรณีที่เหมาะสมลายเซ็นของวิธีการที่เหมาะสมกว่าที่ ommitted cmd เป็นพารามิเตอร์จะถูกกำหนดและใช้ แต่มันอาจจะไม่
JustinC

2

นี่คือความคิดของฉันเอง โปรดทราบว่าฉันไม่แน่ใจเกินไปนี่เป็นวิธีที่ดีที่สุดที่จะไปซึ่งเป็นสาเหตุที่ฉันสร้างคำถามนี้ตั้งแต่แรก

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

เพื่อให้มั่นใจว่ารหัสลูกค้าสามารถตรวจจับข้อยกเว้น "ความล้มเหลว" ได้อย่างหมดจดโดยไม่ต้องจับข้อยกเว้นข้อผิดพลาดโดยไม่ได้ตั้งใจฉันสร้างคลาสข้อยกเว้นของตัวเองสำหรับข้อยกเว้นความล้มเหลวทั้งหมดในตอนนี้และบันทึกไว้ในวิธีการ ฉันจะทำให้พวกเขาตรวจสอบข้อยกเว้นใน Java

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

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


1

กฎง่ายๆ:

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

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


0

แม้แต่จาวาก็ไม่ได้ "ทำเอกสาร" ยกเว้นทั้งหมด แม้จะมีข้อกำหนดว่าthrowจะมีการกล่าวถึงข้อยกเว้นทุกข้อในthrowsประโยคบรรทัดใด ๆ ของโค้ดสามารถส่ง a RuntimeExceptionโดยไม่จำเป็นต้องประกาศในลายเซ็นเมธอด


สิ่งนี้ขัดกับคำแนะนำที่เป็นที่นิยม - โดยเฉพาะ, จาวาที่มีประสิทธิภาพ, 2nd ed, รายการ 62 คือ "เอกสารทั้งหมดยกเว้นโดยแต่ละวิธี" ในความเป็นจริง Bloch ยอมรับว่าข้อยกเว้นที่ไม่ได้ตรวจสอบนั้นโดยทั่วไปแล้วสำหรับข้อผิดพลาดในการเขียนโปรแกรม แต่ควรบันทึกไว้อย่างระมัดระวังด้วยเนื่องจากเป็น "วิธีที่ดีที่สุด" ในการจัดทำเอกสารเงื่อนไขเบื้องต้นของวิธีการ ฉันไม่แน่ใจว่าฉันเห็นด้วยหรือไม่ หากฉันบันทึกเอกสารการประหารชีวิตฉันจะทำให้พวกเขาเป็นส่วนหนึ่งของสัญญาส่วนต่อประสานและอาจต้องเพิ่มรหัสเพื่อให้พวกเขายังคงเหมือนเดิมหากการเปลี่ยนแปลงการใช้งานของฉัน
Medo42

1
สำหรับผู้เชี่ยวชาญทุกคนมีผู้เชี่ยวชาญตอบโต้ Bruce Eckel ผู้เขียนThinking ที่โด่งดังใน Javaเคยเป็นค่ายที่ได้รับการตรวจสอบแล้วและมีการเปลี่ยนแปลงด้านข้าง มีการสนทนาที่ดีระหว่าง Eckels กับ Anders Hejlsbergผู้สร้าง C # ซึ่งไม่ได้ตรวจสอบข้อยกเว้น
Ross Patterson

0

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


2
คุณพิจารณา (เช่น) คำนวณ (หรือค่าความผิดพลาด) NULL เป็นข้อผิดพลาดการเขียนโปรแกรมหรือข้อผิดพลาดสัญญาหรือไม่ ฉันไปด้วยความแตกต่างของคุณ แต่ขอบเขตไม่ชัดเจนดังนั้น :)
แอนดรู

หากคำนวณเป็นโมฆะจากการโต้แย้งที่ผ่านเข้ามา (เช่นอาร์กิวเมนต์ว่างหรือสิ่งที่ไม่ถูกต้อง) นั่นเป็นข้อผิดพลาดของสัญญา หากคำนวณเป็นโมฆะเนื่องจากชิ้นส่วนของรหัสที่ไม่ดีนั่นเป็นข้อผิดพลาดในการเขียนโปรแกรม หากควรคำนวณค่าว่างมันไม่ใช่ข้อผิดพลาด ฉันไม่เห็นความกำกวมใด ๆ ในตัวอย่างนี้
J.Ashworth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.