ใช้การยืนยันกับการโยนข้อยกเว้น?


38

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

ดังนั้นเมื่อใดที่ฉันควรจะทำ: เมื่อใดจึงเหมาะสมที่จะใช้การยืนยันและเมื่อใดที่เหมาะสมที่จะทำการยกเว้น


3
ฉันคิดว่าคำถามนี้ควรถูกถามใน stackoverflow ถึงแม้ว่ามันอาจจะถูกถามถึงสิบครั้งก็ตามดังนั้นคุณอาจพบคำตอบมากมายที่นั่น
281377

คำตอบ:


50

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

กฎง่ายๆที่ฉันมักจะปฏิบัติตามคือการตรวจสอบข้อขัดแย้งของฟังก์ชั่นส่วนตัวกับการยืนยันและการใช้ข้อยกเว้นสำหรับข้อโต้แย้งของฟังก์ชั่นสาธารณะ / การป้องกัน


จุดที่ดีเกี่ยวกับการใช้ข้อยกเว้นสำหรับอินพุตภายนอก ฉันจะเพิ่มผลลัพธ์เช่นกัน - ปัญหาเมื่อพยายามสร้าง / เขียนไปยังไฟล์ / ฐานข้อมูลเป็นต้น
ChrisF

13
และแน่นอนคุณจะพบว่าคำยืนยันเหล่านั้นถูกกระตุ้นในการผลิต +1 สำหรับการยืนยันสิ่งส่วนตัวพร้อมยืนยัน! บางทีคุณอาจพูดว่า "ใช้การยืนยันเมื่อคุณอยู่ในการควบคุมอินพุตอย่างเต็มที่"?
Frank Shearar

1
อย่างน้อยในจาวาคุณต้องเปิดใช้งานการตรวจสอบการยืนยันด้วยพารามิเตอร์บรรทัดคำสั่ง -ea ซึ่งหมายความว่าการยืนยันจะไม่มีประสิทธิภาพนอกจากคุณจะเปิดใช้อย่างชัดเจน
Bill Michell

29

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

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


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

3

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

เช่นใน C

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

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


2
ฉันไม่คิดว่าเป็นความคิดที่ดีที่จะวางพฤติกรรมที่สง่างามไว้เบื้องหลังการยืนยันในสภาพเดียวกัน อย่างหลีกเลี่ยงไม่ได้เพราะพฤติกรรมที่สง่างามมีอยู่เพียงในเวอร์ชันการผลิตรหัสที่ควรจะจัดการกับพฤติกรรมที่สง่างามจะได้รับการทดสอบไม่ดีและความผิดพลาดเช่นเดียวกับที่ไม่ดีเท่าถ้าไม่แย่กว่านั้นรหัสจะมี
Sebastian Redl

0

ปัญหาอย่างหนึ่งของ asserts สำหรับฉันก็คือพวกมันถูกปิดใช้งานโดยปริยายใน Java

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.