วิธีเอาชนะการเขียนโปรแกรมโดยบังเอิญ? [ปิด]


24

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

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

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

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

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

แก้ไข:

สรุปจากโพสต์ของคุณ:

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

BTW มันยากที่จะยอมรับคำตอบมันยากจริงๆ คำตอบทั้งหมดนั้นยอดเยี่ยมจริงๆ :)


6
มันจะช่วยให้ผู้คนที่อาจจะไม่ได้อ่านหนังสือเล่มนี้เป็นเวลานานจะมีการเชื่อมโยงเช่นpragprog.com/the-pragmatic-programmer/extracts/coincidence
btilly

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

@ Robbie Dee คุณช่วยอธิบายให้กระจ่างขึ้นอีกหน่อยได้ไหม? ฉันไม่ได้รับคุณ แน่นอนฉันมีอาชีพการเขียนโปรแกรมสั้น ๆ และนั่นคือเหตุผลของแท็กจูเนียร์โปรแกรมเมอร์
py_script

2
@py_script ฉันแค่ทำให้จุดที่คุณสามารถเจอรหัสของคุณเองได้อย่างง่ายดายในหลายปีต่อมา (และถูกมันสับสน) ในฐานะคนอื่น ดังนั้นถ้าคุณเริ่มต้นด้วยนิสัยที่ดีสิ่งนี้จะจ่ายเงินปันผลในภายหลัง
Robbie Dee

คำตอบ:


26

คุณไม่ต้องคิดล่วงหน้าเพียง แต่ชัดเจนในสิ่งที่ทำและชัดเจนในสิ่งที่คุณทำอยู่ตอนนี้

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

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

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

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

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

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


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

1
ฉันมีตัวอย่างมากมาย ในโครงการ C ++ ฉันสร้างคลาสโดยไม่ใช้วิธีการทำให้เป็นสตริง เมื่อฉันสร้างสิ่งเหล่านี้การดีบักก็ง่ายขึ้น ในโครงการ Perl เรามีแฮชการกำหนดค่าที่นักพัฒนาซอฟต์แวร์แต่ละคนมีสำเนา tweaked ของแต่ละการกำหนดค่าใหม่ การเพิ่มพารามิเตอร์การกำหนดค่าเป็นความเจ็บปวดเพราะคุณต้องแก้ไขการกำหนดค่าของนักพัฒนาทุกคน ฉันเขียนระบบเทมเพลตสำหรับแฮชและนั่นก็ง่ายขึ้น ในระบบการรายงานฉันเพิ่มคุณสมบัติเพื่อแสดงผลลัพธ์ระดับกลาง การพัฒนาของฉันเร่งความเร็วขึ้นและผมยังได้รายงานข้อผิดพลาดของผู้ใช้ ...
btilly

1
แผนกการเงินตรวจสอบตรรกะของฉันและพบข้อสงสัยที่ฉันผิดและข้อผิดพลาดของฉันคืออะไร (ผมก็ตั้งใจ squashing แถวที่ซ้ำกันกับUNIONที่ผมจำเป็นต้องUNION ALL.) และอื่น ๆ
btilly

1
ภายในหนึ่งเดือน ฉันมักจะพบว่าทุกครั้งที่ฉันแตะรหัสที่ฉันรู้สึกว่าควรได้รับการปรับโครงสร้างใหม่ แต่ไม่ได้รับการปรับสภาพใหม่จะต้องใช้เวลาเกือบเท่าที่จะต้องทำการปรับปรุงใหม่
Amy Blankenship

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

41

มันสวยมากเดือดลงไปไม่ต้องเดา โปรแกรมเมอร์ใหม่ส่วนใหญ่ทำ แต่ฉันเห็นทหารผ่านศึกทำเช่นกันเพราะพวกเขาคิดว่ามันช่วยประหยัดเวลาในการวิจัย สิ่งที่ไม่ทำงานเพื่อให้คุณเพิ่ม+1หรือ-1, เปลี่ยนtrueไปfalseหรือในทางกลับกันการสั่งซื้องบบางส่วนเพิ่มหรือความล่าช้าในการเปลี่ยนแปลงลำดับความสำคัญของการเปลี่ยนแปลงด้ายและการแปลงขนาดเล็กอื่น ๆ โดยทั่วไปการทดสอบพีชคณิตแบบสุ่มจนกว่าจะทำงาน

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

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


1
จุดที่ดีเยี่ยม +1 ไม่มีที่ไหนนี้ใช้มากกว่าการแก้ไขรหัส ...
ร็อบบี้ดี

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

ฉันยอมรับ. เมื่อหันหน้าไปทางเอนซินโดรมไม้จิ้มฟันก็สามารถจะง่ายต่อการกอง \ s จนกว่าจะทำงานกว่าจะคิดออกชั้นหลายวิธีที่จะหนีคุณกำลังต่อสู้กับ ...
btilly

16

ความคิดเห็นที่น่ากลัวที่สุดที่ฉันเคยพบในโปรแกรมคือ

อย่าแตะต้องสิ่งนี้ มันได้ผล. เราไม่รู้วิธีหรือเหตุผล แต่มันใช้งานได้ 1

และมันก็เป็นเพียงแค่น่ากลัวเพราะมันยอมรับว่าชิ้นส่วนของรหัสเป็นผลมาจากการเขียนโปรแกรมโดยบังเอิญ

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


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


2
สิ่งนี้เรียกอีกอย่างว่าการเข้ารหัสไก่ของวูดูc2.com/cgi/wiki?VoodooChickenCoding
minusSeven

1
แม้ว่า coder จะเชื่อว่าเป็นจริงความคิดเห็นประเภทนั้นก็ไม่ได้ช่วยอะไรมากมาย รหัสอาจมีความซับซ้อน แต่ถ้าคุณต้องอ่านรหัสคุณอาจคิดว่ามันตรงไปตรงมา ความคิดเห็นทั้งหมดจะเพิ่มความหวาดระแวง!
Robbie Dee

3
สิ่งนี้สามารถเกิดขึ้นได้เมื่อทำการบำรุงรักษา codebase เก่าในภาษาที่ทีมพัฒนาส่วนใหญ่ในปัจจุบันไม่ค่อยพอใจ
pcurry

ดังนั้นเป็ดยางจึงไม่เพียง แต่ช่วยในการแก้ไข ดี ... ฉันคิดว่าเรากำลังทำงานใน บริษัท เดียวกันเรามีความคิดเห็นมากมายเช่นนี้: P
py_script

มีบางสถานการณ์ที่การแก้ไขใช้งานได้เนื่องจากความผิดพลาดใน API และไม่มีการแก้ไขที่ดีและมีเหตุผล การดีบัก lib บุคคลที่สามที่คอมไพล์แล้วบางส่วนสามารถทำงานได้ลึกเท่ากับการดีบักเคอร์เนล และแม้ว่าคุณจะพบปัญหา แต่หลังจากการดีบักหลายชั่วโมงคุณก็สามารถทำได้เล็กน้อย ดังนั้นคุณเข้าใกล้ปัญหาที่แตกต่าง คุณปรับใช้โมเดล "กล่องดำ" ซึ่งบังคับให้คุณเขียนโปรแกรมโดยบังเอิญ คุณเล่นกับพฤติกรรมแปลก ๆ ของกล่องดำและถ้าคุณจัดการเพื่อให้มันทำงานได้ตามที่คุณต้องการ GREAT เพิ่มความคิดเห็นด้วย "magic do not touch" และเดินหน้าต่อไป
Radu Simionescu

7

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

ในหลาย ๆ ด้านเมื่อคุณไม่รู้ว่าจะทำอะไรคุณก็แค่ลองผิดลองถูก ลองอะไร ถ้ามันใช้งานได้ดีเยี่ยมถ้าไม่ลองอย่างอื่น

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

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

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

(แน่นอนว่าใช้กับโปรแกรมเมอร์ปรุงรสด้วยเช่นกัน แต่ประสบการณ์ของฉันที่นี่ส่วนใหญ่เป็นผู้เริ่มต้นใหม่ที่สมบูรณ์)


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

2

มันง่ายเกินไปที่จะเขียนโค้ดทดสอบและแก้ไข "ในสายการแข่งรถ" คุณมีฟังก์ชั่นบางอย่างที่ให้ X & Y, สร้าง Z. แต่ถ้า X เสียหายและ Y ไม่พร้อมใช้งาน? ถ้าคุณไม่สามารถส่งออก Z จงจำไว้เสมอว่าอะไรที่ผิดพลาดและจดบันทึกสำหรับรอบการทดสอบ

รักษากิจวัตรประจำวันของคุณให้สั้นและสื่อความหมาย - รหัสที่ดีที่สุดต้องการข้อคิดเห็นเล็กน้อย (ถ้ามี)

วิธีการที่มีความหมายชื่อคลาสและตัวแปรจะช่วยให้สามารถอ่านได้ง่ายขึ้น

หากคุณเจอกลิ่นรหัสแล้วหยุด กลิ่นนั้นไม่น่าจะหายไปและความพยายามเล็ก ๆ น้อย ๆ ในตอนนี้สามารถช่วยให้คุณเศร้าโศกมากมายในภายหลัง

รวมการทดสอบในกระบวนการพัฒนาของคุณ ฉันอยากจะสนับสนุนการใช้BDDมากกว่าTDDเพราะมันบังคับให้คุณอธิบายสิ่งที่คุณต้องการบรรลุมากกว่าการสุ่มสี่สุ่มห้าโดยอาศัยการทดสอบแพซึ่งสามารถทำให้คุณรู้สึกถึงความปลอดภัย

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

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