แนะนำรูปแบบการออกแบบ / แนวทางในการเปิดเผย / ยอมรับ / กู้คืนจากข้อผิดพลาดของระบบการจัดการข้อยกเว้น (egs ใน Java, C ++, Perl, PHP)


13

คุณสามารถแนะนำรูปแบบการออกแบบ / แนวทางในการเปิดเผย / ยอมรับ / กู้คืนจากข้อผิดพลาดของระบบการจัดการข้อยกเว้น (Java, C ++, Perl, PHP) หรือไม่

จำเป็นต้องรายงานข้อผิดพลาดบางอย่าง

ข้อผิดพลาดบางอย่างสามารถจัดการภายใน (โดยลองใหม่หรือไม่สำคัญ (สามารถเพิกเฉย)

คุณจัดโครงสร้างรหัสเพื่อจับพวกเขาอย่างไร

แต่จะต้องมีการบันทึกข้อผิดพลาดทั้งหมด

มีแนวทางปฏิบัติที่ดีที่สุดอะไรบ้าง

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

คำถามเฉพาะที่ไม่ใช่ภาษาโปรแกรมทั่วไปที่ใช้กับภาษาการเขียนโปรแกรมสมัยใหม่หลายภาษา แต่ยินดีต้อนรับตัวอย่างภาพประกอบของรูปแบบวิธีการและปรัชญาใน Java, C ++, PHP และ Perl

(ถามด้วยใน stackoverflow: /programming/7432596/recommend-a-design-pattern-approach-to-exposing-tolerating-recovering-from-system) แต่ฉันคิดว่ามันควรถามโปรแกรมเมอร์เช่นกัน ฉันคิดว่าโปรแกรมเมอร์ถาม - ตอบครอบคลุมถึงซอฟต์แวร์ / ปัญหาการเขียนโปรแกรมที่กว้างขึ้น


2
สำหรับฉันคำถามของคุณดูเหมือนจะกว้างเกินไปและเปิดกว้างเกินกว่าที่จะตอบได้อย่างมีประสิทธิภาพ พยายาม จำกัด เฉพาะบางกรณีและเพื่อประเภทแอปพลิเคชัน / สภาพแวดล้อมที่เฉพาะเจาะจง (เช่นแอพ GUI / เซิร์ฟเวอร์ / ... )
PéterTörök


@ PéterTörök, mikera ให้คำตอบที่ดีน่าจะยอมรับพวกเขา
therobyouknow

คำตอบ:


16

การล้มเหลวอย่างรวดเร็วเป็นวิธีการออกแบบที่ยอดเยี่ยมและอาจนับได้ว่าเป็นรูปแบบ: http://en.wikipedia.org/wiki/Fail-fast

ฉันได้พบหลักการหลายประการที่เป็นประโยชน์:

  • พิจารณาข้อยกเว้นซึ่งเป็นส่วนหนึ่งของอินเทอร์เฟซสำหรับแต่ละฟังก์ชั่น / โมดูล - เช่นจัดทำเอกสารและที่เหมาะสม / ถ้าภาษาของคุณรองรับแล้วใช้ข้อยกเว้นที่เลือก
  • อย่าลบล้างความล้มเหลว - หากล้มเหลวอย่าพยายามดำเนินการต่อโดยพยายาม "สมมติ" วิธีดำเนินการต่อ ตัวอย่างเช่นการจัดการแบบพิเศษสำหรับกรณี null มักจะเป็นกลิ่นของรหัสฉัน: หากวิธีการของคุณต้องการค่าที่ไม่เป็นโมฆะมันควรจะโยนข้อยกเว้นทันทีหากพบว่ามีค่า NullPointerException หรือ IllegalArgumentException ที่มีความหมายมากกว่า
  • เขียนการทดสอบหน่วยสำหรับกรณีพิเศษและปกติ - บางครั้งการทดสอบดังกล่าวอาจยุ่งยากในการตั้งค่า แต่ก็คุ้มค่าเมื่อคุณต้องการให้แน่ใจว่าระบบของคุณมีความทนทานต่อความล้มเหลว
  • บันทึกที่จุดที่จับและจัดการข้อผิดพลาด (สมมติว่าข้อผิดพลาดมีความรุนแรงเพียงพอที่จะบันทึก) เหตุผลนี้คือมันบอกเป็นนัยว่าคุณเข้าใจถึงสาเหตุและมีวิธีจัดการกับข้อผิดพลาดดังนั้นคุณสามารถทำให้ข้อความบันทึกมีความหมาย .....
  • ใช้ข้อยกเว้นสำหรับเงื่อนไข / ความล้มเหลวที่ไม่คาดคิดเท่านั้น หากฟังก์ชั่นของคุณ "ล้มเหลว" ในแบบที่คาดหวังจริง ๆ (เช่นการสำรวจเพื่อดูว่ามีอินพุตเพิ่มเติมหรือไม่และหาไม่พบ) ก็ควรส่งคืนการตอบกลับตามปกติ ("ไม่มีอินพุต") อย่าโยนข้อยกเว้น
  • ล้มเหลวอย่างสง่างาม (ให้เครดิตกับ Steven Lowe!) - ทำความสะอาดก่อนที่จะยกเลิกหากเป็นไปได้โดยทั่วไปโดยการคลี่คลายการเปลี่ยนแปลงย้อนกลับการทำธุรกรรมหรือการปลดปล่อยทรัพยากรในคำสั่ง "ในที่สุด" หรือเทียบเท่า การล้างข้อมูลควรเกิดขึ้นในระดับเดียวกับที่ทรัพยากรถูกกำหนดไว้เพื่อความชัดเจนและความสอดคล้องทางตรรกะ
  • หากคุณต้องล้มเหลวล้มเหลวเสียงดัง - ข้อยกเว้นที่ไม่มีส่วนใดของรหัสของคุณที่สามารถจัดการ (เช่นการซึมผ่านระดับสูงสุดโดยไม่ถูกจับ + จัดการ) ควรทำให้เกิดความล้มเหลวในทันทีเสียงดังและมองเห็นได้ ฉันมักจะหยุดโปรแกรมหรืองานและเขียนรายงานข้อยกเว้นแบบเต็มไปที่ System.out

1
ก็ล้มเหลวอย่างสง่างาม - ทำความสะอาดก่อนที่จะยุติหากเป็นไปได้
สตีเวนเอ. โลว์

+1 @mikera สำหรับจุดที่ชัดเจนเกี่ยวกับสิ่งที่ต้องพิจารณา คำตอบที่น่าจะเป็นที่ยอมรับฉันจะปล่อยให้คนอื่นมีส่วนร่วมนานขึ้น
therobyouknow

+1 @Steve A. Lowe - สำหรับการออกแบบที่เน้นผู้ใช้เป็นหลัก เช่นบันทึกไฟล์อย่าปล่อยให้ไฟล์ temp นอนอยู่ ดูคำถามของฉันเกี่ยวกับ "สุขอนามัยข้อมูล" เป็นหัวข้อที่เกี่ยวข้องในรายการคำถามของฉัน
therobyouknow

5

เมื่อทำงานกับข้อยกเว้นใน Java และ. NET และหลังจากอ่านบทความจำนวนมากเกี่ยวกับวิธีการ / เมื่อ / ทำไมที่จะจับข้อยกเว้นในที่สุดฉันก็เกิดขึ้นกับขั้นตอนต่อไปนี้ที่ฉันผ่านในหัวของฉันเมื่อใดก็ตามที่ฉันเห็นข้อยกเว้นที่อาจเกิดขึ้น ยกเว้นฉันต้องจับ (Java) ... แม้ว่ามันจะไม่เกิดขึ้น (ถอนหายใจ ... ) และดูเหมือนว่าจะทำงานอย่างน้อยสำหรับฉัน:

  1. มีประโยชน์อะไรบ้างที่ฉันสามารถทำได้กับข้อยกเว้นนั้น (ยกเว้นการบันทึก) หากคำตอบคือใช่ให้เขียนรหัสวิธีแก้ปัญหาและหากวิธีแก้ปัญหาอาจมีข้อยกเว้นให้ไปที่ 2:
  2. ล้อมรอบข้อยกเว้นเกี่ยวกับข้อยกเว้นรันไทม์แล้วโยนไปที่ 3
  3. ในคลาสระดับสูงกว่าที่เป็นไปได้ที่เริ่มต้นฐานข้อมูล / กระบวนการธุรกรรมจับข้อยกเว้นย้อนกลับธุรกรรมการ rerowrow ข้อยกเว้น
  4. ในระดับระดับบนสุด (ซึ่งอาจจะเป็นหนึ่งที่ทำธุรกรรมที่ได้รับการริเริ่ม) เข้าสู่ระบบข้อยกเว้นการเข้าสู่ระบบโดยใช้กรอบเช่นslf4j (คู่กับlog4jตัวอย่าง) หรือlog4net ถ้าเป็นไปได้ส่งอีเมลข้อยกเว้นโดยตรงไปยังรายชื่อการแจกจ่ายที่ประกอบด้วยนักพัฒนาของแอปพลิเคชัน
  5. หากมี GUI ให้แสดงข้อความแสดงข้อผิดพลาดที่บ่งบอกถึงวิธีการใช้งานที่ง่ายที่สุดที่ทำให้เกิดปัญหา อย่าแสดงข้อยกเว้น / stacktrace ผู้ใช้ไม่สนใจและไม่จำเป็นต้องรู้ว่ามันเป็น NullPointerException

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

ยกเว้นส่วนการบันทึกฉันเห็นด้วยกับประเด็นที่เขียนโดย "mikera"; ฉันจะเพิ่มว่าข้อยกเว้นควรถูกบันทึกครั้งเดียวเท่านั้น

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

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


+1 @Jalayn สำหรับ log4j พูดถึงวิธีการนี่คือสิ่งที่ฉันใช้ดังนั้นจึงเป็นการตอกย้ำให้รู้ว่าคนอื่นเป็นอย่างดี
therobyouknow

0

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

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

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