แต่การหยุดทำงานซอฟต์แวร์ไคลเอ็นต์ของคุณยังคงไม่ดี
แน่นอนที่สุดมันเป็นสิ่งที่ดี
คุณต้องการให้อะไรก็ตามที่ทำให้ระบบอยู่ในสถานะไม่ได้กำหนดเพื่อหยุดระบบเนื่องจากระบบที่ไม่ได้กำหนดสามารถทำสิ่งที่น่ารังเกียจเช่นข้อมูลที่เสียหายจัดรูปแบบฮาร์ดไดรฟ์และส่งอีเมลถึงประธานาธิบดีที่คุกคาม หากคุณไม่สามารถกู้คืนและทำให้ระบบกลับสู่สถานะที่กำหนดการหยุดทำงานเป็นสิ่งที่ต้องรับผิดชอบ นั่นเป็นเหตุผลที่เราสร้างระบบที่ผิดพลาดมากกว่าที่จะฉีกขาดออกจากกันอย่างเงียบ ๆ ตอนนี้แน่นอนว่าเราทุกคนต้องการระบบที่มีความเสถียรซึ่งไม่เคยล่ม แต่เราเพียงต้องการให้ระบบนั้นอยู่ในสถานะที่ปลอดภัยที่คาดการณ์ได้
ฉันได้ยินมาว่ามีข้อยกเว้นในขณะที่การควบคุมการไหลถือว่าเป็น antipattern ที่ร้ายแรง
เป็นเรื่องจริงอย่างแน่นอน แต่มักเข้าใจผิด เมื่อพวกเขาคิดค้นระบบยกเว้นพวกเขากลัวว่าพวกเขากำลังทำลายการเขียนโปรแกรมที่มีโครงสร้าง การเขียนโปรแกรมที่มีโครงสร้างเป็นเหตุผลที่เรามีfor
, while
, until
, break
และเมื่อเราต้องการที่จะทำทั้งหมดที่เป็นcontinue
goto
Dijkstraสอนเราว่าการใช้ goto อย่างไม่เป็นทางการ (นั่นคือการกระโดดไปรอบ ๆ ทุกที่ที่คุณต้องการ) ทำให้การอ่านโค้ดเป็นฝันร้าย เมื่อพวกเขาให้ระบบยกเว้นพวกเขาพวกเขากลัวว่าพวกเขาจะได้รับการปรับปรุงใหม่ ดังนั้นพวกเขาจึงบอกเราว่าอย่า "ใช้มันเพื่อการควบคุมการไหล" หวังว่าเราจะเข้าใจ น่าเสียดายที่พวกเราหลายคนไม่ได้
น่าแปลกที่เรามักจะไม่ใช้ข้อยกเว้นในการสร้างรหัสสปาเก็ตตี้เหมือนที่เคยใช้กับข้ามไป ดูเหมือนว่าคำแนะนำจะทำให้เกิดปัญหามากขึ้น
ข้อยกเว้นพื้นฐานเกี่ยวกับการปฏิเสธสมมติฐาน เมื่อคุณถามว่าไฟล์ถูกบันทึกคุณจะถือว่าไฟล์นั้นสามารถและจะถูกบันทึกไว้ ข้อยกเว้นที่คุณได้รับเมื่อไม่สามารถเกี่ยวกับชื่อที่ผิดกฎหมาย HD เต็มหรือเนื่องจากหนูได้กัดแทะผ่านสายเคเบิลข้อมูลของคุณ คุณสามารถจัดการข้อผิดพลาดเหล่านั้นแตกต่างกันคุณสามารถจัดการข้อผิดพลาดเหล่านั้นในลักษณะเดียวกันทั้งหมดหรือให้ระบบหยุดชะงัก มีเส้นทางที่มีความสุขในรหัสของคุณที่สมมติฐานของคุณจะต้องถือเป็นจริง ทางเดียวหรืออีกข้อยกเว้นพาคุณไปสู่เส้นทางที่มีความสุข พูดอย่างเคร่งครัดใช่มันเป็น "การควบคุมการไหล" แต่นั่นไม่ใช่สิ่งที่พวกเขาเตือนคุณ พวกเขาพูดถึงเรื่องไร้สาระเช่นนี้ :
"ข้อยกเว้นควรยอดเยี่ยม" คำหยาบนี้เกิดขึ้นเนื่องจากผู้ออกแบบระบบยกเว้นต้องการเวลาในการสร้างร่องรอยสแต็ก เมื่อเปรียบเทียบกับการกระโดดไปรอบ ๆ นี่จะช้า มันกินเวลา CPU แต่ถ้าคุณกำลังจะเข้าสู่ระบบและหยุดระบบหรืออย่างน้อยก็หยุดการประมวลผลแบบเร่งรัดเวลาปัจจุบันก่อนที่จะเริ่มการประมวลผลถัดไปจากนั้นคุณมีเวลาที่จะฆ่า หากผู้คนเริ่มใช้ข้อยกเว้น "สำหรับการควบคุมการไหล" สมมติฐานเหล่านั้นเกี่ยวกับเวลาทั้งหมดออกไปนอกหน้าต่าง ดังนั้น "ข้อยกเว้นควรได้รับการยกเว้น" ได้ถูกมอบให้กับเราเพื่อการพิจารณาด้านประสิทธิภาพ
สำคัญยิ่งกว่านั้นคือไม่ทำให้เราสับสน ใช้เวลานานแค่ไหนที่คุณจะสังเกตเห็นวงวนไม่สิ้นสุดในโค้ดด้านบน
อย่าส่งคืนรหัสข้อผิดพลาด
... เป็นคำแนะนำที่ดีเมื่อคุณอยู่ในฐานรหัสซึ่งโดยทั่วไปจะไม่ใช้รหัสข้อผิดพลาด ทำไม? เพราะไม่มีใครจำได้ว่าต้องบันทึกค่าส่งคืนและตรวจสอบรหัสข้อผิดพลาดของคุณ มันยังเป็นแบบแผนที่ดีเมื่อคุณอยู่ในซี
OneOf
คุณกำลังใช้การประชุมอื่น ไม่เป็นไรตราบใดที่คุณตั้งค่าการประชุมและไม่เพียงแค่ต่อสู้อีกครั้ง มันสับสนที่จะมีข้อผิดพลาดสองข้อในรหัสฐานเดียวกัน ถ้าอย่างใดคุณได้กำจัดรหัสทั้งหมดที่ใช้การประชุมอื่นแล้วไปข้างหน้า
ฉันชอบการประชุมด้วยตัวเอง หนึ่งในคำอธิบายที่ดีที่สุดของฉันพบที่นี่* :
แต่เท่าที่ฉันชอบฉันยังคงไม่ผสมกับอนุสัญญาอื่น ๆ เลือกอย่างใดอย่างหนึ่งและติดกับมัน 1
1: โดยที่ฉันหมายถึงอย่าทำให้ฉันคิดถึงการประชุมมากกว่าหนึ่งครั้งในเวลาเดียวกัน
ความคิดที่ตามมา:
จากการสนทนานี้สิ่งที่ฉันกำลังจะไปในขณะนี้มีดังนี้:
- หากคุณคาดหวังว่าผู้เรียกในทันทีที่จะจับและจัดการข้อยกเว้นเป็นส่วนใหญ่และทำงานต่อไปอาจจะผ่านเส้นทางอื่นก็อาจจะเป็นส่วนหนึ่งของประเภทกลับ ตัวเลือกหรือ OneOf จะมีประโยชน์ที่นี่
- หากคุณคาดว่าผู้ที่โทรเข้ามาในทันทีจะไม่รับข้อยกเว้นส่วนใหญ่แล้วให้โยนข้อยกเว้นเพื่อบันทึกความบ้าของการส่งผ่านสแต็กด้วยตนเอง
- หากคุณไม่แน่ใจว่าผู้ที่โทรเข้ามาทันทีกำลังทำอะไรอยู่อาจให้ทั้งคู่เช่น Parse และ TryParse
มันไม่ง่ายอย่างนี้จริงๆ หนึ่งในสิ่งพื้นฐานที่คุณต้องเข้าใจคือสิ่งที่เป็นศูนย์
เหลือกี่วันในเดือนพฤษภาคม 0 (เพราะไม่ใช่พฤษภาคมมันเป็นเดือนมิถุนายนแล้ว)
ข้อยกเว้นเป็นวิธีที่จะปฏิเสธสมมติฐาน แต่ไม่ใช่วิธีเดียว หากคุณใช้ข้อยกเว้นเพื่อปฏิเสธสมมติฐานที่คุณออกจากเส้นทางที่มีความสุข แต่ถ้าคุณเลือกค่าที่จะส่งเส้นทางความสุขที่เป็นสัญญาณว่าสิ่งต่าง ๆ ไม่ง่ายอย่างที่คิดเอาไว้คุณสามารถอยู่บนเส้นทางนั้นได้ตราบใดที่มันสามารถจัดการกับค่าเหล่านั้นได้ บางครั้ง 0 ถูกใช้เพื่อหมายถึงบางสิ่งบางอย่างดังนั้นคุณต้องหาค่าอื่นเพื่อทำแผนที่สมมติฐานของคุณที่ปฏิเสธแนวคิดไป คุณอาจจะไม่รู้จักความคิดนี้มาจากการใช้งานในเก่าดีพีชคณิต Monads สามารถช่วยได้ แต่มันไม่จำเป็นต้องเป็น monad เสมอไป
ตัวอย่าง2 :
IList<int> ParseAllTheInts(String s) { ... }
คุณคิดว่ามีเหตุผลที่ดีที่สิ่งนี้จะต้องได้รับการออกแบบมาเพื่อที่จะได้โยนสิ่งใดโดยเจตนาหรือไม่? คาดเดาสิ่งที่คุณจะได้รับเมื่อไม่มีการวิเคราะห์ int ฉันไม่จำเป็นต้องบอกคุณ
นั่นเป็นสัญลักษณ์ของชื่อที่ดี ขออภัยTryParseไม่ใช่ชื่อที่ดีของฉัน
เรามักจะหลีกเลี่ยงข้อยกเว้นในการไม่ได้อะไรเลยเมื่อคำตอบอาจมากกว่าหนึ่งสิ่งในเวลาเดียวกัน แต่ด้วยเหตุผลบางอย่างถ้าคำตอบนั้นเป็นเรื่องเดียวหรือไม่มีสิ่งใดที่เราหมกมุ่นอยู่กับการยืนยันว่ามันให้สิ่งหนึ่งกับเรา
IList<Point> Intersection(Line a, Line b) { ... }
เส้นคู่ขนานจำเป็นต้องทำให้เกิดข้อยกเว้นจริงหรือไม่? จริง ๆ แล้วมันไม่ดีถ้ารายการนี้จะไม่ประกอบด้วยมากกว่าหนึ่งจุด
บางทีความหมายคุณไม่สามารถทำได้ ถ้าเป็นเช่นนั้นมันน่าเสียดาย แต่บางที Monads ที่ไม่มีขนาดตามที่ต้องการList
จะทำให้คุณรู้สึกดีขึ้น
Maybe<Point> Intersection(Line a, Line b) { ... }
Monads เป็นคอลเล็กชั่นวัตถุประสงค์พิเศษเล็ก ๆ น้อย ๆ ที่มีไว้เพื่อใช้ในวิธีการเฉพาะที่หลีกเลี่ยงการทดสอบ เราควรจะหาวิธีจัดการกับพวกเขาโดยไม่คำนึงถึงสิ่งที่พวกเขามี ด้วยวิธีนี้เส้นทางแห่งความสุขยังคงเรียบง่าย หากคุณเปิดและทดสอบทุก Monad ที่คุณสัมผัสว่าคุณใช้ผิด
ฉันรู้ว่ามันแปลก แต่มันเป็นเครื่องมือใหม่ (ดีสำหรับเรา) ดังนั้นให้เวลา ฆ้อนจะมีเหตุผลมากขึ้นเมื่อคุณหยุดใช้สกรู
หากคุณจะตามใจฉันฉันต้องการพูดถึงความคิดเห็นนี้:
ทำไมไม่มีคำตอบที่ชัดเจนว่าทั้งสอง monad ไม่ใช่รหัสข้อผิดพลาดและไม่ใช่ OneOf พวกเขามีพื้นฐานที่แตกต่างกันและคำถามจึงดูเหมือนว่าจะอยู่บนพื้นฐานของความเข้าใจผิด (แม้ว่าจะอยู่ในรูปแบบที่ถูกปรับเปลี่ยน แต่มันก็ยังเป็นคำถามที่ถูกต้อง) - Konrad Rudolph 4 มิ.ย. 18 ที่ 14:08
นี่เป็นเรื่องจริงอย่างแน่นอน Monads นั้นใกล้กับคอลเล็กชันมากกว่าข้อยกเว้นค่าสถานะหรือรหัสข้อผิดพลาด พวกเขาทำภาชนะอย่างดีสำหรับสิ่งต่าง ๆ เมื่อใช้อย่างชาญฉลาด
Result
;-)