ประเด็นสำคัญของการทำงานอย่างมีประสิทธิภาพด้วยรหัสมรดกคืออะไร [ปิด]


133

ฉันเคยเห็นหนังสือทำงานอย่างมีประสิทธิภาพด้วยรหัสมรดกแนะนำสองสามครั้ง ประเด็นสำคัญของหนังสือเล่มนี้คืออะไร?

มีการจัดการกับรหัสดั้งเดิมมากกว่าการเพิ่มการทดสอบหน่วย / การรวมและการเปลี่ยนโครงสร้างอีกครั้งหรือไม่



2
แน่นอนประเด็นคือการเพิ่มการทดสอบแล้ว refactor หนังสือส่วนใหญ่เกี่ยวกับวิธีที่คุณจัดการเพื่อรับโค้ดที่ซับซ้อนอย่างไม่น่าเชื่อภายใต้การทดสอบและมีผู้เปิดตาจำนวนมากในจุดนั้น สมมุติว่า Feathers ไม่มีนักโทษเลย!
Kilian Foth

9
บางทีคุณควรอ่านหนังสือเล่มนี้
HLGEM

ดีมากรีวิวได้ที่นี่: andreaangella.com/2014/03/…
rohancragg

คำตอบ:


157

ปัญหาหลักของรหัสดั้งเดิมคือไม่มีการทดสอบ ดังนั้นคุณต้องเพิ่มบางส่วน (และมากกว่านั้น ... )

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

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

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

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

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

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

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

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


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

99

วิธีที่รวดเร็วในการรับประเด็นสำคัญของการทำงานอย่างมีประสิทธิภาพด้วยรหัสดั้งเดิม

  • อ่านPDF 12 หน้าของ Michael Feathers เขียนขึ้นก่อนหนังสือสองปี
  • ดูการนำเสนอของ Michael Feathers: 68 สไลด์
  • ฟังบทสัมภาษณ์พอดคาสต์กับ Michael Feathers เช่นนี่30 นาทีตอน

3
การเชื่อมโยง MP3 ในหน้า Hanselminutes ที่เสีย แต่หนึ่งบนhanselminutes.com/165/...ไม่ได้เป็น - s3.amazonaws.com/hanselminutes/hanselminutes_0165.mp3
Peter Mortensen

ขอบคุณ rosston สำหรับการแก้ไขลิงก์ PDF ดูเหมือนว่า objectmentor.com ได้ผ่านไปแล้ว - บางที "ลุงบ๊อบ" ก็เลิกกิจการไปแล้ว?
MarkJ

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

40

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

คำสำคัญที่นี่เป็นเพียง - เป็นคำสี่ตัวอักษรที่ไม่ได้อยู่ในคำศัพท์ของโปรแกรมเมอร์ใด ๆ ให้คนเดียวที่ทำงานในระบบมรดก

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

ใช้เวลาเท่าไหร่ในการลงทุนระบบล้านมรดก 20 ปี สมมติว่านักพัฒนา 20 คนสำหรับ 20 ปีคูณ 2,000 ชั่วโมง / ปี (พวกเขาทำงานหนักมาก) ลองเลือกตัวเลข - คุณมีคอมพิวเตอร์เครื่องใหม่และเครื่องมือใหม่และคุณฉลาดกว่าพวกที่เขียนแผ่นนี้ $% ^^ ในตอนแรก - สมมติว่าคุณมีค่าเท่ากับ 10 คุณมี 40 คนปีแล้วคุณมี ...

ดังนั้นคำตอบสำหรับคำถามของคุณคือมีมากขึ้น ตัวอย่างเช่นรูทีนที่มี 1,000 บรรทัด (ฉันมีน้อยกว่า 5000) มันซับซ้อนเกินไปและเป็นปาเก็ตตี้ชิ้นหนึ่ง มันจะ (เพียงอีกสี่ตัวอักษรคำ) ใช้เวลาสองสามวันในการพิจารณาปัจจัยอีกครั้งในกิจวัตร 100 บรรทัดและผู้ช่วยอีก 20 บรรทัดใช่ไหม? ไม่ถูกต้อง. ที่ซ่อนอยู่ใน 1,000 เส้นนั้นคือการแก้ไขข้อบกพร่อง 100 ข้อแต่ละข้อมีความต้องการของผู้ใช้ที่ไม่มีเอกสารหรือตัวพิมพ์ขอบที่ไม่ชัดเจน เป็น 1,000 บรรทัดเพราะรูทีน 100 บรรทัดดั้งเดิมไม่ทำงาน

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

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


2
ขอบคุณสำหรับเคล็ดลับ! คุณมาจากหนังสือหรือเปล่า?
อาร์มันด์

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

7
"เป็น 1,000 บรรทัดเพราะรูทีน 100line ดั้งเดิมไม่ทำงาน" ดังนั้นสิ่งนี้ดูเหมือนจะไม่เกิดขึ้นจริงมากนัก บ่อยกว่านั้นคือ 1,000 บรรทัดเพียงเพราะนักพัฒนาดั้งเดิมพับแขนเสื้อของเขาและเริ่มเขียนโค้ดก่อนที่จะใช้เวลาสักครู่ในการวางแผนหรือออกแบบ
Stephen Touset

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

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

19

มีสองประเด็นสำคัญที่จะนำออกไปจากหนังสือเล่มนี้

  1. รหัสดั้งเดิมคือรหัสใด ๆ ที่ไม่มีการครอบคลุมการทดสอบ
  2. เมื่อใดก็ตามที่คุณต้องเปลี่ยนรหัสดั้งเดิมคุณควรตรวจสอบให้แน่ใจว่ามีรหัสครอบคลุม

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


6
+1 จุดที่ยอดเยี่ยม: "เมื่อใดก็ตามที่คุณต้องทำการเปลี่ยนแปลงรหัสดั้งเดิมให้ใช้เวลาในการลบสถานะเดิม"
จอห์น

3
การลบสถานะเดิมรับคะแนนของฉัน :)
Rachel

7

ในเปลือกถั่วนั้นเป็นความจริง - การเพิ่มการทดสอบและการเปลี่ยนโครงสร้างใหม่เป็นสิ่งที่เกี่ยวข้อง

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

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