เมื่อใดที่ควรมีการยืนยันในรหัสการผลิต [ปิด]


166

มีการอภิปรายที่เกิดขึ้นที่ comp.lang.c ++ มีการตรวจสอบว่ายืนยันหรือไม่ซึ่งใน C ++ นั้นมีอยู่เฉพาะในการสร้างข้อบกพร่องโดยค่าเริ่มต้นควรเก็บไว้ในรหัสการผลิตหรือไม่

เห็นได้ชัดว่าแต่ละโครงการจะไม่ซ้ำกันดังนั้นคำถามของฉันที่นี่คือไม่มากไม่ว่าจะยืนยันควรจะเก็บไว้, แต่ในกรณีนี้เป็นฝากฝัง / ไม่ได้เป็นความคิดที่ดี

โดยการยืนยันฉันหมายถึง:

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

ฉันไม่จำเป็นต้องพูดถึง C หรือ C ++

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

ความเห็น / ประสบการณ์ของคุณคืออะไร

ไชโย

คาร์ล

ดูคำถามที่เกี่ยวข้องที่นี่


การตอบสนองและการปรับปรุง

เฮ้เกรแฮม

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

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

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


เบี่ยงประเด็นเล็กน้อย แต่เป็นประเด็นสำคัญในการอภิปราย

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

คาร์ล


โทมัส

ใช่ฉันมี Code Complete และต้องบอกว่าฉันไม่เห็นด้วยอย่างยิ่งกับคำแนะนำเฉพาะนั้น

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

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

คาร์ล


3
มีการโพสต์ที่เกี่ยวข้องที่น่าสนใจที่ Software Engineering SE (แม้ว่าการสนทนาจะเน้นที่ c ++): หากมีคำยืนยันในงานสร้างรุ่น
ซันนี่

คำตอบ:


84

การยืนยันเป็นความคิดเห็นที่ไม่ล้าสมัย เอกสารเหล่านี้มีจุดประสงค์ทางทฤษฎีใดและไม่ควรเกิดรัฐใด หากมีการเปลี่ยนแปลงรหัสเพื่ออนุญาตให้มีการเปลี่ยนแปลงสถานะผู้พัฒนาจะได้รับแจ้งในไม่ช้าและจำเป็นต้องอัปเดตการยืนยัน


16
@ jkschneider: การทดสอบหน่วยสำหรับการทดสอบสิ่งต่าง ๆ ภายในขอบเขตของรหัสของโปรแกรม การยืนยันเพื่อให้มั่นใจว่าสมมติฐานที่ใช้รหัสนั้นเป็นจริงในความเป็นจริงก่อนที่จะประมวลผลรหัสต่อไปภายใต้สมมติฐานเหล่านั้น พวกเขาเป็น "เอกสาร" ในแง่ที่ว่าหากพวกเขาไม่ได้เป็นอย่างนั้นโปรแกรมจะยกเลิกระบุสมมติฐานและระบุว่าข้อสันนิษฐานนั้นไม่ได้เกิดขึ้น นอกจากนี้คุณยังสามารถอ่านการยืนยันเป็นเอกสารที่แน่นอนในรหัสแน่นอน

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

1
โดยเฉพาะอย่างยิ่งการยืนยันนั้นให้ข้อมูลและไม่สามารถใช้งานได้ การยืนยันด้วยตนเองไม่มีผลกับโฟลว์ของโปรแกรมหรือผลลัพธ์ ข้อยกเว้นในทางกลับกันการเปลี่ยนแปลงการไหลของโปรแกรมและทำให้ผลลัพธ์
yoyo

59

อนุญาตให้ฉันอ้างอิงรหัสของ Steve McConnell ให้สมบูรณ์ ส่วนเกี่ยวกับการยืนยันคือ 8.2

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

อย่างไรก็ตามภายหลังในส่วนเดียวกันคำแนะนำนี้จะได้รับ:

สำหรับรหัสที่มีประสิทธิภาพสูงให้ยืนยันและจัดการข้อผิดพลาดต่อไป

ฉันคิดว่าตราบใดที่ประสิทธิภาพการทำงานไม่เป็นปัญหาให้ออกจากการยืนยัน แต่แทนที่จะแสดงข้อความให้เขียนลงไฟล์บันทึก ฉันคิดว่าคำแนะนำนั้นอยู่ใน Code Complete แต่ฉันไม่พบมันในตอนนี้


7
ผมคิดว่าสิ่งที่อ้างที่สองจากรหัสวิธีการที่สมบูรณ์แบบคือการที่คุณควรจะมียืนยัน - ซึ่งจะได้รับการเรียบเรียงออกมาในรหัสการผลิต - และคุณควรนอกจากนี้ยังมี "ถ้า {AttemptGracefulRecovery ();} (สภาพ!)" คือดอน อย่าปล่อยให้ผู้ที่ละเมิดโปรแกรมขัดข้องโปรแกรม
yoyo

34

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

ถ้ามันไม่คุ้มค่าในการพิสูจน์ว่ามันมีประสิทธิภาพมากกว่ามันก็ไม่คุ้มค่าที่จะเสียสละความชัดเจนในการเล่นการพนัน "- Steve McConnell 1993

http://c2.com/cgi/wiki?ShipWithAssertionsOn


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

5
assert ref != null;แตกต่างจากif (ref == null) throw new IllegalArgumentException();คุณไม่ควรใช้อันแรกสำหรับเงื่อนไขที่อาจเป็นเท็จ คุณต้องใช้assertสำหรับสิ่งที่ไม่สามารถเท็จ ตัวอย่างint i = -1 * someNumber; i = i * i;จากนั้นจึงเตือนผู้คนiในเชิงบวกในภายหลังassert i > 0;
กัปตันแมน

1
"ที่จริงแล้วสิ่งที่แย่ที่สุดที่เกิดขึ้นคือเมื่อโค้ดขัดข้องเนื่องจากสิ่งที่ไม่ใช่การยืนยันหากโค้ดนั้นจะล้มเหลวในภายหลังอย่างแน่นอนด้วยความน่าจะเป็น 100% การยืนยันจะต้องอยู่ที่นั่นอย่างแน่นอน" - นี่คือการแบ่งขั้วที่ผิดพลาด
Rob Grant

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

@supercat ฉันไม่เห็นด้วยกับความคิดเห็นที่ฉันอ้าง
Rob Grant

21

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

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

คำถามที่น่าสนใจกว่านี้คือในขั้นตอนการทดสอบของคุณคุณปิดการยืนยันเมื่อใด


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

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

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

จุดรวมของคำสั่ง assert คือคุณสามารถเปิดหรือปิดการตรวจสอบ ถ้าคุณปล่อยไว้ในการผลิตทำไมต้องใช้คำสั่ง assert?
MiguelMunoz

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

16

คำยืนยันไม่ควรอยู่ในรหัสการผลิต หากการยืนยันโดยเฉพาะดูเหมือนว่ามันอาจเป็นประโยชน์ในรหัสการผลิตก็ไม่ควรเป็นการยืนยัน if( condition != expected ) throw exceptionมันควรจะมีการตรวจสอบข้อผิดพลาดเวลาทำงานคือสิ่งที่รหัสเช่นนี้

คำว่า 'ยืนยัน' ได้มาหมายถึง "การตรวจสอบเวลาการพัฒนาเท่านั้นซึ่งจะไม่ถูกดำเนินการบนสนาม"

หากคุณเริ่มคิดว่าการยืนยันอาจนำไปสู่สนามคุณจะต้องเริ่มคิดอย่างเป็นอันตรายเช่นหลีกเลี่ยงไม่ได้ว่าการยืนยันที่ได้รับนั้นคุ้มค่าหรือไม่ ไม่มีการยืนยันซึ่งไม่คุ้มค่าที่จะทำ คุณไม่ควรถามตัวเองว่า "ฉันควรจะยืนยันเรื่องนี้หรือไม่?" คุณควรถามตัวเองว่า "มีอะไรฉันลืมยืนยันบ้างไหม"


6

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

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


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

5

ใน C ++ ของฉันฉันกำหนด REQUIRE (x) ซึ่งเป็นเหมือน assert (x) ยกเว้นว่ามันจะพ่นข้อยกเว้นถ้าการยืนยันนั้นล้มเหลวใน build build

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

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


พวกเขายังบอกด้วยว่าคุณไม่ควรแสดงข้อความยืนยันต่อแฮ็กเกอร์เพราะพวกเขาเป็นเบาะแสที่มีค่าสำหรับการบุกเข้ามา
DaveWalley

4

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


2

หากพวกเขาได้รับการจัดการเช่นเดียวกับข้อผิดพลาดอื่น ๆ ฉันไม่เห็นปัญหากับมัน โปรดจำไว้ว่าแม้ว่าการยืนยันที่ล้มเหลวใน C เช่นเดียวกับภาษาอื่น ๆ จะเพิ่งออกจากโปรแกรมและมักจะไม่เพียงพอสำหรับระบบการผลิต

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


2

ซอฟต์แวร์เซิร์ฟเวอร์ฐานข้อมูลของเรามีทั้งการยืนยันและตรวจแก้จุดบกพร่อง การยืนยันการแก้ปัญหาเป็นเพียงแค่นั้น - พวกเขาจะถูกลบออกในรหัสการผลิต การยืนยันการผลิตจะเกิดขึ้นก็ต่อเมื่อ (a) มีเงื่อนไขบางอย่างที่ไม่ควรมีอยู่และ (b) เป็นไปไม่ได้ที่จะกู้คืนจากเงื่อนไขนี้ได้อย่างน่าเชื่อถือ การยืนยันการผลิตบ่งชี้ว่ามีข้อบกพร่องในซอฟต์แวร์หรือเกิดความเสียหายของข้อมูลบางประเภท

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

ต้องบอกว่าเรายังพยายามหลีกเลี่ยงการยืนยันการผลิตในการปฏิบัติงานที่สำคัญ


5
ฉันจะเรียกว่า "การยืนยันการผลิต" ของคุณ "ข้อยกเว้น" และรหัสดังกล่าว
DaveWalley

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

1

ฉันเห็นการยืนยันว่าเป็นการทดสอบในหน่วย มีประโยชน์สำหรับการทดสอบที่รวดเร็วในขณะที่กำลังพัฒนา แต่ท้ายที่สุดการยืนยันเหล่านั้นควรได้รับการปรับโครงสร้างใหม่เพื่อทดสอบภายนอกในการทดสอบหน่วย


ยืนยัน: ระบุข้อเท็จจริงหรือความเชื่อ ไม่ใช่สำหรับการทดสอบ (เท่านั้น) แต่สำหรับการระบุสิ่งที่คุณคิดว่าเป็นจริง (เช่นข้อสมมติฐานของคุณ) เพื่อให้โปรแกรมของคุณจะไม่ดำเนินการต่อหากสมมติฐานของคุณผิดด้วยเหตุผลบางประการ ตัวอย่างเช่นนี่เป็นการใช้การยืนยันที่ถูกต้อง: assert (pow (1,0) <1) มันไม่ใช่สถานที่ที่เหมาะสมสำหรับการตรวจสอบข้อผิดพลาดเพราะถ้ามันไม่เป็นจริงแล้วคณิตศาสตร์สมัยใหม่ทั้งหมดนั้นผิดและ ... ดีคุณจะเริ่มจัดการกับมันอย่างไร การจัดการสมมติฐานที่ไม่ถูกต้องนั้นอยู่นอกขอบเขตของโปรแกรม คุณเชื่อมั่น แต่คุณยืนยันแล้ว

1

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

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

อย่างไรก็ตามสมมติว่า fopen () ของคุณได้รับการบันทึกว่าส่งคืนการจัดการไฟล์ที่เปิดและถูกต้อง คุณเปิดไฟล์และส่งผ่านไปยังฟังก์ชัน readfile () ของคุณ

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

ดังนั้น readfile () {ยืนยัน (fptr! = NULL); .. } มีความเหมาะสมในกรณีนี้ในขณะที่การจัดการข้อผิดพลาดเต็มรูปแบบไม่ได้ (ไม่สนใจข้อเท็จจริงที่ว่าการอ่านไฟล์จริง ๆ แล้วจะต้องมีระบบจัดการข้อผิดพลาดอยู่แล้ว)

และใช่การยืนยันเหล่านั้นควรอยู่ในรหัสการผลิตเว้นแต่จะมีความจำเป็นอย่างยิ่งที่จะต้องปิดการใช้งาน แม้ว่าคุณควรปิดการใช้งานเฉพาะในส่วนที่สำคัญต่อประสิทธิภาพ


1

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

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

สถานการณ์ไม่ได้เป็นการเชิญ ยืนยันการใช้งานแม้ในการผลิต


0

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

ฉันเสนอตัวอย่าง

file = create-some-file();
_throwExceptionIf( file.exists() == false, "FILE DOES NOT EXIST");

ต่อต้าน

file = create-some-file();
ASSERT(file.exists());

แอปพลิเคชันจะจัดการกับการยืนยันอย่างไร ฉันชอบtry catchวิธีการเดิมในการจัดการกับข้อผิดพลาดร้ายแรง


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

0

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

ตามที่ฉันยืนยันทั้งหมดของคุณมีความสำคัญในการปล่อย dev ไม่ใช่ในการผลิต relase บางคนต้องถูกเก็บไว้คนอื่น ๆ จะต้องถูกทิ้ง


0

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

มีสองสามจุดที่จะหลีกเลี่ยงการเปิดใช้งานการยืนยันในรหัสการผลิต: 1. คุณไม่ต้องการให้ผู้ใช้ปลายทางเห็นข้อความเช่น "ASSERTION ล้มเหลว MyPrivateClass.cpp บรรทัด 147. ผู้ใช้ไม่ใช่วิศวกร QA ของคุณ 2. การรับรองอาจ มีอิทธิพลต่อประสิทธิภาพ

อย่างไรก็ตามมีเหตุผลหนึ่งที่สำคัญในการออกจากการยืนยัน: ASSERTION อาจมีผลต่อประสิทธิภาพและเวลาและบางครั้งเรื่องนี้น่าเศร้า (โดยเฉพาะในระบบฝังตัว)

ฉันมักจะลงคะแนนให้ออกจากการยืนยันในรหัสการผลิต แต่ให้แน่ใจว่าลึกหนาบางพิมพ์ยืนยันเหล่านี้ไม่ได้สัมผัสกับผู้ใช้

~ Yitzik


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

อนุญาตให้ฉันปรับแต่งความคิดเห็นของฉัน: 1. การยืนยันจะตรวจสอบสมมติฐานของเรา หากสมมติฐานของเราผิดเราก็หมายความว่ามีข้อผิดพลาดในรหัสของเรา 2. รหัสของเราไม่ควรยืนยันการใช้รหัสของเรา เช่นฟังก์ชั่นไม่ควรล้มเหลวในการยืนยันหากมีสิ่งผิดปกติในการป้อนข้อมูลจากผู้ใช้ เราจะส่งกลับข้อผิดพลาดและผู้ใช้ควรจัดการ (เขาสามารถยืนยันความสำเร็จ) 3. ฉันชอบออกจากการยืนยันในการผลิต - แต่พฤติกรรมอาจจะมีการแก้ไข ฉันยอมรับว่าไม่มีการจัดการข้อผิดพลาดที่เหมาะสม ล้มเหลวในการยืนยัน == ข้อผิดพลาด .. แต่ระบบอาจเริ่มต้นตัวเองใหม่แทนที่จะหยุดและรอการรีบูต
Yitshak Yarom

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

-8

การยืนยันเป็นข้อผิดพลาดบริสุทธิ์และเรียบง่ายดังนั้นควรจัดการเหมือน

เนื่องจากข้อผิดพลาดควรได้รับการจัดการในโหมดการปล่อยดังนั้นคุณไม่จำเป็นต้องยืนยัน

ประโยชน์หลักที่ฉันเห็นสำหรับการยืนยันคือการแตกตามเงื่อนไข - มันง่ายกว่าการติดตั้งมากกว่าการเจาะผ่านหน้าต่างของ VC เพื่อตั้งค่าบางอย่างที่ใช้รหัส 1 บรรทัด


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

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