คำเตือน! โปรแกรมเมอร์ C ++ ที่เข้ามาที่นี่พร้อมกับแนวคิดที่แตกต่างกันของวิธีการจัดการข้อยกเว้นควรพยายามตอบคำถามที่เกี่ยวกับภาษาอื่นอย่างแน่นอน!
รับความคิดนี้:
ตัวอย่างเช่นสมมติว่าเรามีการดึงทรัพยากรซึ่งดำเนินการคำขอ HTTP และส่งคืนข้อมูลที่ดึงมา และแทนที่จะมีข้อผิดพลาดเช่น ServiceTemporaryUnavailable หรือ RateLimitExceeded เราจะเพิ่ม RetryableError แนะนำผู้บริโภคว่าควรเพิ่งลองใหม่อีกครั้งและไม่สนใจความล้มเหลวที่เฉพาะเจาะจง
... สิ่งหนึ่งที่ฉันอยากจะแนะนำก็คือคุณอาจจะสับสนกับการรายงานข้อผิดพลาดกับแนวทางการปฏิบัติเพื่อตอบสนองในทางที่อาจลดความน่าเชื่อถือของรหัสของคุณหรือต้องการ "จุดแปล" จำนวนมากสำหรับข้อยกเว้น .
ตัวอย่างเช่นถ้าฉันจำลองธุรกรรมที่เกี่ยวข้องกับการโหลดไฟล์มันอาจล้มเหลวด้วยเหตุผลหลายประการ บางทีการโหลดไฟล์นั้นเกี่ยวข้องกับการโหลดปลั๊กอินที่ไม่มีอยู่ในเครื่องของผู้ใช้ บางทีไฟล์อาจเสียหายและเราพบข้อผิดพลาดในการแยกวิเคราะห์
ไม่ว่าจะเกิดอะไรขึ้นสมมติว่าแนวทางการดำเนินการคือการรายงานสิ่งที่เกิดขึ้นกับผู้ใช้และแจ้งให้เขาทราบถึงสิ่งที่เขาต้องการจะทำ ("ลองอีกครั้งโหลดไฟล์อื่นยกเลิก")
Thrower vs. Catcher
แนวทางการดำเนินการนั้นใช้โดยไม่คำนึงถึงข้อผิดพลาดประเภทใดที่เราพบในกรณีนี้ ไม่ได้ฝังอยู่ในแนวคิดทั่วไปของข้อผิดพลาดในการแยกวิเคราะห์ แต่ไม่ได้ฝังลงในแนวคิดทั่วไปของการไม่สามารถโหลดปลั๊กอิน มันฝังอยู่ในแนวคิดของการพบข้อผิดพลาดดังกล่าวในระหว่างบริบทที่แม่นยำในการโหลดไฟล์ (การรวมกันของการโหลดไฟล์และความล้มเหลว) ดังนั้นโดยทั่วไปผมเห็นมันหยาบพูดเป็นcatcher's
ผู้รับผิดชอบในการกำหนดหลักสูตรของการดำเนินการในการตอบสนองต่อข้อยกเว้นโยน (เช่น: แจ้งให้ผู้ใช้มีตัวเลือก) thrower's
ไม่ได้
กล่าวอีกนัยหนึ่งไซต์ที่throw
โดยทั่วไปแล้วจะมีข้อยกเว้นที่ไม่มีข้อมูลเชิงบริบทโดยเฉพาะอย่างยิ่งหากฟังก์ชันที่ใช้งานโดยทั่วไป แม้ในบริบทที่เสื่อมโทรมโดยสิ้นเชิงเมื่อพวกเขามีข้อมูลนี้คุณก็จะเข้าโค้งในแง่ของพฤติกรรมการกู้คืนโดยฝังลงในthrow
ไซต์ เว็บไซต์ที่catch
เป็นเว็บไซต์ที่มีข้อมูลจำนวนมากที่สุดเพื่อกำหนดวิธีการดำเนินการและให้ศูนย์กลางสำหรับการปรับเปลี่ยนหากแนวทางการดำเนินการนั้นควรเปลี่ยนไปสำหรับธุรกรรมที่ให้ไว้
เมื่อคุณเริ่มพยายามโยนข้อยกเว้นจะไม่รายงานสิ่งที่ผิด แต่ลองพิจารณาว่าจะทำอย่างไรนั่นอาจทำให้รหัสทั่วไปของคุณและความยืดหยุ่นลดลง ข้อผิดพลาดในการวิเคราะห์คำไม่ควรนำไปสู่พรอมต์ประเภทนี้ทุกครั้ง แต่จะแตกต่างกันไปตามบริบทที่มีข้อผิดพลาดเกิดขึ้น (รายการที่ถูกโยน)
The Blind Thrower
โดยทั่วไปแล้วการออกแบบการจัดการข้อยกเว้นจำนวนมากมักจะหมุนรอบความคิดของนักโยนตาบอด ไม่ทราบว่าจะมีการยกเว้นได้อย่างไรหรือที่ไหน เช่นเดียวกับการกู้คืนข้อผิดพลาดในรูปแบบที่เก่ากว่าโดยใช้การเผยแพร่ข้อผิดพลาดด้วยตนเอง ไซต์ที่พบข้อผิดพลาดไม่รวมการดำเนินการของผู้ใช้พวกเขาฝังข้อมูลขั้นต่ำเพื่อรายงานว่าเกิดข้อผิดพลาดประเภทใด
Inverted Responsibilities และ Generalizing Catcher
เมื่อคิดถึงเรื่องนี้ให้ละเอียดยิ่งขึ้นฉันพยายามจินตนาการถึง codebase ชนิดที่อาจกลายเป็นสิ่งล่อใจ จินตนาการของฉัน (อาจผิด) คือทีมของคุณยังคงเล่นบทบาทของ "ผู้บริโภค" ที่นี่และใช้รหัสโทรศัพท์ส่วนใหญ่เช่นกัน บางทีคุณอาจมีธุรกรรมที่แตกต่างกันจำนวนมาก ( try
บล็อกจำนวนมาก) ที่ทุกคนสามารถเรียกใช้เป็นข้อผิดพลาดชุดเดียวกันและจากมุมมองการออกแบบทั้งหมดควรนำไปสู่การดำเนินการกู้คืนที่สม่ำเสมอ
เมื่อคำนึงถึงคำแนะนำที่ชาญฉลาดจากLightness Races in Orbit's
คำตอบที่ดี (ซึ่งฉันคิดว่ามาจากความคิดที่มุ่งเน้นในห้องสมุดขั้นสูง) คุณอาจยังคงอยากที่จะโยนข้อยกเว้น "สิ่งที่ต้องทำ" เพียงใกล้กับเว็บไซต์กู้คืนธุรกรรมเท่านั้น
อาจเป็นไปได้ที่จะหาคนกลางเว็บไซต์จัดการธุรกรรมทั่วไปจากที่นี่ซึ่งจริงๆแล้วเป็นการรวมศูนย์ที่เกี่ยวข้องกับ "สิ่งที่ต้องทำ" แต่ยังอยู่ในบริบทของการจับ
สิ่งนี้จะใช้เฉพาะถ้าคุณสามารถออกแบบฟังก์ชั่นทั่วไปบางอย่างที่การทำธุรกรรมด้านนอกทั้งหมดเหล่านี้ใช้ (เช่น: ฟังก์ชั่นที่ป้อนฟังก์ชั่นอื่นในการโทรหรือคลาสฐานธุรกรรมนามธรรมที่มีพฤติกรรม overridable )
ทว่าผู้รับผิดชอบในการรวมศูนย์ผู้ใช้ในการดำเนินการเพื่อตอบสนองต่อข้อผิดพลาดต่าง ๆ ที่เป็นไปได้และยังอยู่ในบริบทของการจับแทนที่จะโยน ตัวอย่างง่าย ๆ (Python-ish pseudocode และฉันไม่ได้เป็นนักพัฒนา Python ที่มีประสบการณ์เพียงเล็กน้อยดังนั้นอาจมีวิธีที่เป็นไปได้มากกว่าในเรื่องนี้):
def general_catcher(task):
try:
task()
except SomeError1:
# do some uniformly-designed recovery stuff here
except SomeError2:
# do some other uniformly-designed recovery stuff here
...
[หวังว่าด้วยชื่อที่ดีกว่าgeneral_catcher
] ในตัวอย่างนี้คุณสามารถส่งผ่านฟังก์ชั่นที่มีงานที่ต้องทำ แต่ยังคงได้รับประโยชน์จากพฤติกรรมจับแบบทั่วไป / แบบรวมสำหรับข้อยกเว้นทุกประเภทที่คุณสนใจและดำเนินการต่อเพื่อขยายหรือแก้ไขส่วน "สิ่งที่ต้องทำ" ทั้งหมด คุณชอบจากตำแหน่งกลางนี้และยังอยู่ในcatch
บริบทที่ได้รับการสนับสนุนโดยทั่วไป เหนือสิ่งอื่นใดเราสามารถป้องกันไม่ให้ไซต์ขว้างปาเกี่ยวกับตัวเองด้วย "สิ่งที่ต้องทำ" (การรักษาความคิดของ "นักเลงตาบอด")
หากคุณพบว่าไม่มีคำแนะนำใด ๆ ที่เป็นประโยชน์ที่นี่และมีการล่อลวงอย่างมากที่จะโยนข้อยกเว้น "สิ่งที่ต้องทำ" อย่างไรก็ตามส่วนใหญ่โปรดทราบว่านี่เป็นการต่อต้านการใช้สำนวนอย่างน้อยที่สุดรวมทั้งอาจทำให้ท้อใจ