คุณจะลบรหัสที่ดูเหมือนไม่เคยใส่ออกมาได้อย่างไร


125

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

ความคิดสองประการเกิดขึ้นในใจ

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

  2. ทำการบันทึกในส่วนของรหัสนั้นและดูความถี่ที่ได้รับในทางปฏิบัติ หลังจากการประหารชีวิตมากพอคุณควรมีความมั่นใจในการลบรหัสนั้นอย่างปลอดภัย

มีความคิดที่ดีขึ้นหรืออะไรบางอย่างที่เป็นแนวทางแบบบัญญัติหรือไม่?


55
อาจเป็นประโยชน์ในการดูประวัติการควบคุมเวอร์ชัน: สร้าง "รหัสตาย" เมื่อใด มันดูเหมือนตายไปแล้วเมื่อมันถูกสร้างขึ้น? มีการตรวจสอบรหัสอื่น (ซึ่งแก้ไขหรือลบไปแล้ว) ซึ่งใช้งานพร้อมกับสร้างขึ้นหรือไม่
ChrisW

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

16
ฉันถาม - "ทำไมต้องลบมัน?" ถ้ามันถูกใช้ในกรณีขอบบางอย่างที่เรียกว่าครั้งเดียวในดวงจันทร์สีน้ำเงินแสดงว่าคุณแตกหัก หากไม่เคยใช้งานและคุณทิ้งไว้ที่นั่นความเสียหายก็คือไฟล์ที่เรียกใช้งานจะใหญ่กว่าเล็กน้อย เว้นแต่จะมีไว้สำหรับอุปกรณ์ฝังตัวนี้เป็นเรื่องใหญ่หรือไม่? แสดงความคิดเห็นติดมันและใช้เวลาของคุณอย่างมีประสิทธิผล
mickeyf

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

9
@MichaelJ ประเด็นของฉันคือไม่ควรอยู่ที่นั่นตั้งแต่แรก และถ้าฉันทิ้งมันไว้สถานการณ์แย่กว่าเดิม: ตอนนี้นักพัฒนารายอื่น ๆ ที่เข้าแถวก็ต้องตรวจสอบเช่นกัน ยิ่งอยู่นานเท่าไรก็ยิ่งใช้เวลาทำความเข้าใจมากขึ้นเท่านั้น นี่คือค่าใช้จ่ายของรหัสฟุ่มเฟือย
jpmc26

คำตอบ:


112

ในโลกแฟนตาซีที่สมบูรณ์แบบที่ฉันมีการทดสอบหน่วย 100% ฉันจะลบมันรันการทดสอบหน่วยของฉันและเมื่อไม่มีการทดสอบเปลี่ยนเป็นสีแดงฉันยอมรับมัน

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

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

249
จากการสังเกตสถานะของโครงการซอฟต์แวร์ขนาดใหญ่ที่วิศวกรใช้เวลาสิบถึงสิบสองปีที่ผ่านมาส่วนใหญ่ใช้วิธี "ไม่คุ้มค่า" ในการลบรหัสที่ไม่จำเป็นออกไปฉันไม่สามารถแนะนำวิธีนี้ได้
njuffa

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

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

42
@Weyland Yutani นั่นไม่ตรงกับประสบการณ์ของฉันเลย รหัสฟุ่มเฟือยที่น่าจะเป็นไปได้ส่วนใหญ่ที่ผมเขียนมานั้นดีพอสมควรและสมบูรณ์แบบตามข้อกำหนดของซอฟต์แวร์แพลตฟอร์มฮาร์ดแวร์หรือรุ่นของระบบปฏิบัติการที่มีอยู่ก่อนหน้าทศวรรษที่ผ่านมาจำเป็นต้องแก้ไขข้อบกพร่องหรือข้อ จำกัด ในห่วงโซ่เครื่องมือ .
njuffa

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

84

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

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

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

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

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


14
รั้วของ Chesterton สันนิษฐานว่าการค้นพบมาจากการคิดล้วนๆและไม่มีการขอความช่วยเหลือซึ่งเป็นปรัชญาโบราณของกรีกโบราณ วิธีการทางวิทยาศาสตร์มีความทันสมัยมากขึ้น - คิดค้นการทดลองควบคุมเพื่อกำหนดผลที่ตามมาของการลบโครงสร้าง เพื่อให้แน่ใจว่าฉันจะไม่เสนอการทดลองนี้ในการผลิต แต่ถ้าไม่มีทางเลือกและค่าใช้จ่ายในการทดลองใช้งานสูงมากดีฉันจะออกจากที่ทำงานอย่างรวดเร็วซึ่งไม่ได้หมายความว่าฉันจะปลอดภัยในการเรียนรู้ว่าทำไมมีรหัสบางอย่าง - ความเสี่ยงส่วนบุคคลในงานดังกล่าวสูงเกินไป .
kojiro

15
@kojiro นั่นเป็นเรื่องจริงมาก ฉันชอบคิดว่า Chesterton จะไม่เป็นไรถ้าฉันในฐานะ "นักปฏิรูปสมัยใหม่" มาและพูดว่า "ฉันไม่รู้ว่าทำไมรั้วนี้ถึงอยู่ที่นี่ฉันยอมรับ แต่ฉันต้องการทาสีแดงเพื่อดูว่า ที่ให้ข้อมูลใหม่แก่ฉัน "เชสเตอร์ตันน่าจะมีความสุขกับมัน
Cort Ammon

41
เมธอดการถอดรหัสนาฬิกาโหมดเคอร์เนล VMS OS SYS $ ASCTIM มีบรรทัดของรหัสที่ช่วยแก้ไขการลอยของดาวฤกษ์ของวสันตวิษุวัต ไม่มีหน่วยทดสอบของ DEC ที่ใช้รหัสนี้ มันวิ่งหนึ่งครั้ง - ถูกต้อง - วันที่ 2000-02-28 เวลา 23: 59: 59: 999 มันจะไม่ทำงานอีกจนกว่าจะถึงปี 2400 โปรดอย่าลบมัน
AI Breveleri

13
@ AIBreveleri ฉันควรหวังว่ามีความคิดเห็นในรหัสอธิบายตัวเองและไม่เพียง แต่ที่นี่ใน StackExchange: D
Kyle Strand

11
@ KyleStrand คุณกำลังพูดถึงอะไร? นี่คือเอกสารประกอบ คุณสามารถนึกถึงสถานที่ที่ดีกว่าในการใส่ข้อมูลสำคัญเพื่อให้คนอื่นค้นพบได้ดีกว่า StackExchange หรือไม่? ;-)
Cort Ammon

43

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


11
ฉันไม่ใช่ downvoter แต่จะเกิดอะไรขึ้นถ้าส่วนของโค้ดที่คุณสงสัยว่าไม่เคยถูกเรียกใช้นั้นไม่ใช่ฟังก์ชั่นหรือคลาสที่สมบูรณ์ แต่เป็นส่วนของเมธอด / ฟังก์ชัน
Tulains Córdova

9
สิ่งนี้อาจไม่น่าเชื่อถือเสมอไป - ขึ้นอยู่กับภาษาบางภาษาอนุญาตให้มีการเรียกใช้เมธอดแบบไดนามิก ตัวอย่างเช่น PHP:$object->$variableMethod($arg1, $arg2);
Dezza

9
@ TulainsCórdovaถ้าอย่างนั้นนี่อาจไม่ใช่ทางออกที่ดีอย่างเห็นได้ชัด สำหรับโซลูชันที่เป็นไปได้ทั้งหมดให้ใช้หากเหมาะสมในบริบทที่กำหนด แต่อาจจะgrepเป็นเช่น ฟังก์ชั่นครอบคลุมส่วนรหัสสามารถให้เบาะแสเกี่ยวกับวิธีการใช้งานฟังก์ชั่นและดังนั้นจึงเนื้อหา
piwi

7
"เช่นถ้าชื่อถูกกล่าวถึงในความคิดเห็นหรือในไฟล์เอกสารหรือสคริปต์" - หรือถ้ามีคนใช้การสะท้อนเพื่อเรียกวิธีการ (ถ้าใช้ภาษาระดับสูง / OO) แม้ว่าจะยังไม่ถูกต้องแม่นยำ 100% เนื่องจากบางภาษารองรับวิธีการค้นหาและเรียกใช้วิธีที่ไม่เหมาะสม
aroth

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

30
  • ระบุรหัสที่ดูเหมือนตาย (การวิเคราะห์แบบคงที่และอื่น ๆ )
  • เพิ่มข้อความบันทึกสำหรับการร้องขอรหัสที่ถูกอ้างถึงทุกครั้ง เป็นเรื่องง่ายด้วยฟังก์ชั่น / วิธีการ; กับสมาชิกคงที่เช่นค่าคงที่มันยุ่งยากกว่า บางครั้งคุณสามารถทำเครื่องหมายรหัสว่าเลิกใช้แล้วและรันไทม์จะบันทึกข้อความให้คุณโดยอัตโนมัติ ปล่อยให้รหัสเป็นอย่างอื่นเหมือนเดิม
    • บันทึกข้อความเมื่อโหลดโมดูลที่ตายแล้ว: ภาษาส่วนใหญ่มีวิธีเรียกใช้การเริ่มต้นแบบคงที่ในเวลาโหลดซึ่งสามารถสำรองไว้ได้
    • ตรวจสอบให้แน่ใจว่าข้อความบันทึกของคุณมีการติดตามสแต็กที่เหมาะสมเพื่อให้คุณเข้าใจสิ่งที่เรียกว่ารหัสที่ถูกกล่าวหาว่าไม่ทำงาน
  • เรียกใช้รหัสที่เปลี่ยนแปลงผ่านชุดทดสอบทั้งหมดของคุณ ห้องทดสอบของคุณควรทดสอบในช่วงเวลาพิเศษเช่นการข้ามเที่ยงคืนหนึ่งรอบไตรมาสหนึ่งรอบปี ฯลฯ ดูที่บันทึกปรับปรุงความเข้าใจของคุณเกี่ยวกับสิ่งที่ตายไป โปรดทราบว่าการทดสอบหน่วยอาจทดสอบรหัสที่ตายแล้วโดยเฉพาะในขณะที่ไม่มีการทดสอบหน่วยอื่นและไม่มีการทดสอบการรวมเข้าด้วยกัน
  • เรียกใช้รหัสที่มีการเปลี่ยนแปลงในการผลิตเป็นเวลาสองสามสัปดาห์ ตรวจสอบให้แน่ใจว่าทุกกระบวนการเป็นระยะเช่นงาน ETL cron เดือนละครั้งทำงานในช่วงเวลานี้
  • ดูบันทึก สิ่งที่บันทึกไว้นั้นไม่ได้ตายไปจริง การปิดสคริปท์ของกราฟการโทรไปยังรหัสที่เหลือนั้นก็อาจจะไม่ตายเช่นกันแม้ว่ามันจะไม่ถูกเรียกใช้ก็ตาม วิเคราะห์มัน บางทีบางสาขาอาจตายอย่างปลอดภัย (เช่นทำงานกับ API ของบริการที่สูญพันธุ์ไปแล้ว) ในขณะที่บางส่วนยังไม่ได้ บางทีโมดูล / คลาสทั้งหมดถูกโหลดเฉพาะค่าคงที่ที่กำหนดไว้ในนั้นและคุณสามารถเลิกใช้งานได้อย่างง่ายดาย
  • สิ่งที่เหลืออยู่นั้นตายอย่างปลอดภัยและสามารถลบออกได้

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

7
@nocomprende จะเกิดอะไรขึ้นถ้ารหัสนี้ใช้สำหรับการทำงานสิ้นปีเท่านั้นและคุณเรียกใช้การทดสอบของคุณรันเดือนกุมภาพันธ์ - พฤศจิกายนคุณจะไม่พบการใช้งานแม้ว่าคุณจะทำโปรไฟล์เกือบทั้งปี
Erik

1
@ 9000 ฉันเห็นด้วยในทางทฤษฎี แต่ระบบดั้งเดิมนั้นเต็มไปด้วยการพึ่งพาที่ซ่อนอยู่ซึ่งสามารถขัดขวางการทดสอบประเภทนี้ได้ สำหรับตัวอย่างการทดสอบในการทำงานคุณจำเป็นต้องรู้ว่ามีการมีเพศสัมพันธ์ทางโลกบางชนิด ถ้าการมีเพศสัมพันธ์ทางโลกอยู่นอกรหัสที่คุณกำลังทดสอบคุณจะไม่เห็นมันในรหัสและรู้ว่าการมีเพศสัมพันธ์ทางโลกนั้นเป็นปัจจัย ยกตัวอย่างเช่นไซโลรหัสติดตั้งในGAC หลายปีที่ผ่านมาไซโล B ถามไซโล A เพื่อเพิ่มเส้นทางโค้ดสำหรับรายงานที่พวกเขาต้องการเรียกใช้กับข้อมูลของไซโล A เธซเธ
Erik

1
@ 9000 ต่อ ตอนนี้โค้ดของไซโล B มีการเชื่อมต่อทางชั่วคราวกับเส้นทางโค้ด "ตาย" ในโค้ดของไซโล A ที่ไม่ชัดเจนโดยเพียงแค่ดูที่โค้ดของไซโล A คุณจะทดสอบหน่วยการมีเพศสัมพันธ์ทางโลกนี้อย่างไรเนื่องจากการมีเพศสัมพันธ์ทางโลกนั้นมีเฉพาะในรหัสของไซโล B โดยไม่ต้องคุยกับไซโล B แม้ว่าเวลาจะไม่เป็นปัจจัยในรหัสของคุณ (ไซโล A) ดังนั้นการทดสอบทางโลกจะเป็นอย่างไร
Erik

2
ใครจำความตื่นตระหนกของY2k ได้บ้าง รหัสบางอย่างถูกต้องในปี 2000 เพราะมันผิดสำหรับ 2100! เรามีปัญหาที่อาจเกิดขึ้นครั้งเดียวในรอบ 100 ปีหรือแม้แต่ครั้งเดียวในรอบ 400 ปี
Steve Barnes

16

นอกเหนือจากคำตอบที่มีอยู่แล้วที่กล่าวถึงคุณยังสามารถลบรหัสซ้ำ ๆ หลาย ๆ รุ่นได้อีกด้วย

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

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


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

นี่ตอบคำถามที่ถามในชื่อเรื่อง แต่ถ้าคุณถามฉันคำถามนั้นมีชื่อผิด ชื่อเรื่องจะถามวิธีการลบรหัส แต่เนื้อหานั้นเกี่ยวกับวิธีการระบุว่ารหัสนั้นปลอดภัยที่จะลบในตอนแรกหรือไม่ คุณตอบแบบเดิมแน่นอน แต่ฉันไม่แน่ใจว่านั่นคือสิ่งที่ OP ถามจริงๆ
underscore_d

7

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

แต่รหัสไม่ใช่สินทรัพย์มันเป็นความรับผิดชอบ

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

หากคุณยังไม่แน่ใจอย่างน้อยต้องเพิ่มการทดสอบเพื่อออกกำลังกายรหัสซอมบี้


ขั้นตอนที่ 1: ลบรหัสทั้งหมด ขั้นตอนที่ 2: นำสิ่งที่ต้องการกลับมา ขั้นตอนที่ 3: ทำซ้ำ

1
@ เอเดรียนฉันสามารถดึงความสนใจของคุณไปยัง Knight Capital ได้หรือไม่? en.wikipedia.org/wiki/ ...... - ในกรณีที่คุณต้องการหนุนจุดของคุณด้วยการอ้างอิงถึงมัน พวกเขาโดยนัยแล้วเพราะรหัสเก่าบางส่วนกลับมามีชีวิตอีกครั้งและพวกเขาก็เสียเงินไปเกือบ 500 ล้านเหรียญ การสอบถามที่ตามมามุ่งเน้นไปที่ขั้นตอนการเผยแพร่ของพวกเขา แต่ปัญหาหลักคือ "การทำงานที่ไม่ได้ถูกลบ"
SusanW

6

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

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

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

อ่านเพิ่มเติมเกี่ยวกับการสลับที่นี่: https://martinfowler.com/articles/feature-toggles.html


6

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

เพียงเปลี่ยนชื่อของเมธอด (เช่นเปลี่ยนDoSomethingเป็นDoSomethingX) จากนั้นเรียกใช้บิลด์

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

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

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


8
นี้เป็นคำแนะนำที่ ok สำหรับการเขียนโปรแกรมภาษาที่ไม่ได้มีเต็มรูปแบบไดนามิก / การเชื่อมโยงล่าช้า อย่างไรก็ตามสำหรับผู้ที่มีมันเป็นเรื่องยาก และแน่นอน - รหัสอาจใช้วิธีการแม้ว่าจะไม่เคยใช้ในการผลิต
eis

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

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

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

1
ใช่เราไม่เห็นด้วยจริงๆ คำนี้มีความหมายแตกต่างกันในภาษาที่ไม่มีความผูกพันแบบเต็มล่าช้า (เช่นฉันอธิบายไว้ในความคิดเห็นแรก) เมื่อคุณผูกเมธอดที่รันไทม์ - ในภาษาที่สามารถเพิ่มและลบเมธอดรันไทม์ได้ทันทีคุณกำลังใช้การเชื่อมโยงแบบช้าในวิธีที่ฉันเข้าใจว่าต้องทำ สิ่งนี้เป็นจริงในภาษาสไตล์ ruby ​​/ python / smalltalk และคุณก็ไม่มีไฟล์แผนที่แยกต่างหาก เนื่องจากโดยเฉพาะทับทิมและไพ ธ อนมีการใช้กันอย่างแพร่หลายฉันไม่เห็นด้วยกับความคิดของคุณว่า "โดยทั่วไป" หมายถึงอะไร
eis

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

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

3
สิ่งนี้จะใช้งานได้ในจินตนาการเมื่อการทดสอบครอบคลุมเกือบ 90% แต่จะเกิดอะไรขึ้นถ้าคุณมีโครงการที่มีรหัส 100.000 บรรทัด นั่นเป็นเหตุผลที่ฉันอธิบายให้ลองทดสอบรหัสและหากไม่มีการทดสอบถึงรหัส ... มันอาจจะตาย
Markus Lausberg

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

@JohannesHahn ฉันคิดว่าคุณหมายถึง "รหัสการผลิต" ซึ่งเป็นรหัสที่ทำงานในสภาพแวดล้อมการผลิต
jpmc26

@ jpmc26 ใช่แน่นอน
โยฮันเนสฮาห์น

3

การลบรหัสที่ไม่สามารถเข้าถึงได้

ในภาษาที่มีการพิมพ์แบบคงที่คุณควรทราบว่ารหัสนั้นสามารถเข้าถึงได้จริงหรือไม่: ลบ, รวบรวม, หากไม่มีข้อผิดพลาดมันไม่สามารถเข้าถึงได้

น่าเสียดายที่ไม่ใช่ทุกภาษาที่จะพิมพ์แบบคงที่และไม่ใช่ภาษาที่พิมพ์แบบคงที่ทั้งหมดจะมีหลักการ สิ่งที่อาจผิดพลาดได้ ได้แก่ (1) การไตร่ตรองและ (2) การบรรทุกเกินพิกัดที่ไม่มีหลักการ

หากคุณใช้ภาษาแบบไดนามิกหรือภาษาที่มีการสะท้อนที่มีประสิทธิภาพเพียงพอที่ชิ้นส่วนของรหัสที่อยู่ภายใต้การตรวจสอบสามารถเข้าถึงได้ในเวลาทำงานผ่านการสะท้อนดังนั้นคุณไม่สามารถพึ่งพาคอมไพเลอร์ได้ ภาษาดังกล่าวรวมถึง Python, Ruby หรือ Java

หากคุณใช้ภาษาที่มีการโอเวอร์โหลดที่ไม่ได้คาดการณ์ไว้ดังนั้นเพียงแค่ลบการโอเวอร์โหลดก็สามารถเปลี่ยนความละเอียดของการโอเวอร์โหลดไปเป็นโอเวอร์โหลดอื่นได้อย่างเงียบ ๆ ภาษาดังกล่าวบางภาษาอนุญาตให้คุณตั้งโปรแกรมการเตือน / ข้อผิดพลาดเวลาคอมไพล์ที่เกี่ยวข้องกับการใช้งานรหัสมิฉะนั้นคุณไม่สามารถพึ่งพาคอมไพเลอร์ได้ ภาษาดังกล่าวรวมถึง Java (ใช้@Deprecated) หรือ C ++ (ใช้[[deprecated]]หรือ= delete)

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

คิวหัวข้อถัดไป ...


การลบรหัสที่อาจไม่ได้ใช้

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

ในกรณีนี้ไม่ว่าจะเป็นภาษาใดรหัสสามารถเข้าถึงได้และสามารถใช้เครื่องมือวัดระยะเวลาทำงานเท่านั้น

ในอดีตที่ผ่านมาฉันใช้วิธีการ 3 เฟสในการลบรหัสดังกล่าวสำเร็จ:

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

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

หวังว่าแอปพลิเคชันส่วนใหญ่จะมีรอบการทำงานที่สั้นลง

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


1
ที่จริงแล้วใน C ++ คุณสามารถทำเครื่องหมายโอเวอร์โหลดของผู้ต้องสงสัยว่าเป็นการ[[deprecated]]ระบุไซต์ที่เรียกเวอร์ชันนั้น จากนั้นคุณสามารถตรวจสอบพวกเขาเพื่อดูว่าพฤติกรรมของพวกเขาจะเปลี่ยนไปหรือไม่ อีกวิธีหนึ่งคือกำหนดโอเวอร์โหลดของคุณเป็น= delete- ในกรณีนี้คุณจะต้องใช้อาร์กิวเมนต์อย่างชัดเจนเพื่อใช้เวอร์ชันอื่นอย่างใดอย่างหนึ่ง
Toby Speight

@TobySpeight: จริงและเป็นทางเลือกที่ดีเช่นกัน ขอให้ฉันแก้ไขสิ่งต่อไปนี้
แมทธิว

"หมอมันเจ็บเมื่อฉันทำอย่างนี้" " อย่าทำอย่างนั้น! " อย่าใช้วิธีที่ทำให้โค้ดไม่สามารถจัดการได้

2

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

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

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

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

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

IMHO ความคิดเห็นนั้นไม่จำเป็นและเป็นตัวเลือกสำหรับการลบ


12
หากฉันมีการควบคุมเวอร์ชันที่เทียบเท่าการคัดค้านของภรรยาของฉันจะถูกยกเลิกได้อย่างง่ายดาย ดังนั้นด้วยการลบรหัส: มันไม่ใช่ความผิดฆ่า พื้นที่เก็บข้อมูลไม่เคยถูกทิ้ง
JDługosz

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

@nocomprende ไม่มีที่ใดในหัวข้อนี้ที่ระบุว่าการสนทนา จำกัด เฉพาะการออกแบบ / ภาษา OOP เท่านั้น ฉันไม่แน่ใจว่าทำไมคุณถึงคิดว่าเกี่ยวข้องกัน
underscore_d

1

บางทีคอมไพเลอร์ก็สังเกตเห็นว่ามันไม่ได้ทำให้ยุ่งยาก

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

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

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


1
ไม่ใช่ภาษาทั้งหมดที่ถูกคอมไพล์ไม่ใช่คอมไพเลอร์ทั้งหมดที่มีการออปติไมซ์และการออปติไมซ์ทั้งหมดนั้นไม่เท่ากันส่วนมากจะไม่ลบโค้ดที่ไม่ถูกเรียกใช้ในกรณีที่รหัสนั้นมีเหตุผล หากรหัสอยู่ใน shared library / DLL รหัสนั้นจะไม่ถูกลบ
Steve Barnes

1
@SteveBarnes ใช่แล้วถ้าคุณไม่ได้ทำ LTO และเชื่อมโยงทุกอย่างเข้าด้วยกันคุณจะรู้สึกเจ็บปวด นั่นคือที่ได้รับ
Navin

1

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

PHP:

public function deleteFoo()
{
    error_log("In deleteFoo()", 3, "/path/to/log");
}

ปรากฎว่าใช้รหัส! บางวิธี AJAX เรียกว่า "วิธีการ: ลบ elem = ฟู" ซึ่งมีการตัดแบ่งแล้วและเรียกว่ามีcall_user_func_array ()

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


มีห้องสมุดสำหรับ PHP และ Perl ที่เรียกว่า Tombstone (php: github.com/scheb/tombstone ) ที่มีประโยชน์ที่นี่
Alister Bulman

0

ใช้grepหรือเครื่องมือใด ๆ ที่คุณมีอยู่ก่อนคุณอาจพบการอ้างอิงถึงรหัส (ไม่ใช่เดิมคำแนะนำ / คำแนะนำของฉัน)

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

คุณสามารถแก้ไขฟังก์ชั่น / บล็อกของรหัสเพื่อเขียนว่ามันถูกใช้ในล็อกไฟล์ หากไม่มีข้อความดังกล่าว "บันทึกไว้" ในไฟล์บันทึกคุณอาจลบรหัสบันทึกได้

ปัญหาสองประการ:

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

  2. ติดตามผู้โทร ในภาษาระดับสูงบางภาษา (เช่น Python) คุณสามารถย้อนกลับได้อย่างง่ายดาย แต่ในภาษาที่รวบรวมคุณจะต้องบันทึกที่อยู่ผู้ส่งคืนลงในบันทึกและบังคับให้มีการถ่ายโอนข้อมูลหลักเมื่อออก (จุดที่ 1)
    ใน C นี้ควรจะค่อนข้างง่าย: ใช้บล็อกเงื่อนไข (เช่น. #ifdef ... #endif) เพื่อใช้เมื่อคุณรู้ว่ามันจะทำงาน (และได้ทดสอบว่ามัน) และเพียงแค่อ่านที่อยู่ผู้ส่ง จากสแต็ก (อาจหรืออาจต้องใช้ภาษาแอสเซมบลีแบบอินไลน์)

การบันทึกข้อโต้แย้งในไฟล์บันทึกอาจจะมีประโยชน์หรือไม่ก็ได้


0

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

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

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

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

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

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


0

แนวทางของฉันซึ่งฉันมักจะคิดว่าเป็นมาตรฐานอุตสาหกรรมในกรณีนี้แปลก ๆ ที่ยังไม่ได้กล่าวถึง:

รับดวงตาคู่ที่สอง

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

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


0

คำตอบง่ายๆสำหรับคำถามของคุณคือคุณไม่สามารถลบรหัสที่คุณไม่เข้าใจได้อย่างปลอดภัยซึ่งรวมถึงการไม่เข้าใจว่าจะถูกเรียกใช้อย่างไร จะมีความเสี่ยง

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

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

ในที่สุดคุณก็เข้าใจมันทิ้งไว้คนเดียวหรือใช้โอกาส


0

ในกรณีที่นักพัฒนาของรหัสในคำถามที่ยังคงมีอยู่, ตรวจสอบการกำจัดรหัสกับเขา นอกจากนี้อ่านความคิดเห็นในรหัส

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

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

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

การสนทนากับผู้เขียนอาจเปิดเผยว่ารหัสเป็นเศษประวัติของสิ่งที่ถูกลบออกหรือไม่เสร็จดังนั้นจึงปลอดภัยที่จะลบ


-1

ฉันเห็นด้วยอย่างยิ่งกับจุดแรกของ Markus Lausberg: ควรวิเคราะห์รหัสด้วยความช่วยเหลือของเครื่องมือ สมองของลิงไม่น่าเชื่อถือกับงานประเภทนี้ !!

ภาษาโปรแกรมมาตรฐานส่วนใหญ่สามารถใช้ใน IDE และ IDE ทุกตัวที่ควรค่าแก่การเรียกว่ามีคุณสมบัติ "find for usages all usages" ซึ่งเป็นเครื่องมือที่เหมาะสมสำหรับสถานการณ์เช่นนี้ (Ctrl + Shift + G ใน Eclipse เป็นต้น)

แน่นอน: เครื่องมือวิเคราะห์แบบคงที่ไม่ได้สมบูรณ์แบบ เราจะต้องตระหนักถึงสถานการณ์ที่ซับซ้อนมากขึ้นซึ่งการตัดสินใจว่าวิธีการที่เป็นปัญหานั้นเกิดขึ้นที่รันไทม์เท่านั้นและไม่ช้าก็เร็ว (การโทรผ่าน Reflection การเรียกไปที่ "eval" - ฟังก์ชั่นในภาษาสคริปต์ ฯลฯ )


5
บางทีสมองลิงไม่ควรเขียนโค้ด? "ไม่มีใครแตะต้องด้วยมือมนุษย์ " เคยเป็นวลีทางการตลาด ฉันนึกภาพกอริลลาที่ทำงานอยู่เสมอ

3
(สมอง Ape เขียนเครื่องมือด้วย) (Shhh! คุณจะทำลายเรื่องราว!)

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

1
... การวิเคราะห์โค้ดแบบคงที่นั้นน่าเบื่องานซ้ำ ๆ ซึ่งทำได้ดีที่สุดโดยคอมพิวเตอร์ ประเภทของงานที่สามารถดำเนินการได้อย่างน่าเชื่อถือโดยคอมพิวเตอร์ แต่ไม่น่าเชื่อถืออย่างแน่นอนเมื่อดำเนินการโดยสมองของลิง สิ่งหลังควรใช้เฉพาะกับสิ่งที่คอมพิวเตอร์ไม่สามารถทำได้เช่นการค้นหาการสะท้อนกลับที่ยุ่งยากและการโทรแบบใช้สาย
โยฮันเนสฮาห์น

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

-1

ความเป็นไปได้สองอย่าง:

  1. คุณมีการทดสอบครอบคลุม 99% + : ลบรหัสและใช้งานเสร็จ
  2. คุณไม่มีการครอบคลุมการทดสอบที่น่าเชื่อถือ: จากนั้นคำตอบคือการเพิ่มคำเตือนการคัดค้าน นั่นคือคุณเพิ่มรหัสบางส่วนไปยังสถานที่ที่ทำสิ่งที่มีสติ (บันทึกคำเตือนไปยังสถานที่ที่มองเห็นได้ง่ายซึ่งไม่ขัดแย้งกับการใช้งานแอปพลิเคชันของคุณแบบวันต่อวัน) จากนั้นปล่อยให้มันหลนสองสามเดือน / ปี หากคุณไม่เคยพบเหตุการณ์ใด ๆ เกิดขึ้นให้แทนที่การคัดค้านด้วยสิ่งที่ทำให้เกิดข้อยกเว้น ปล่อยให้มันยืนอยู่พักหนึ่ง ในที่สุดลบทุกอย่างอย่างสมบูรณ์

2
สิ่งนี้ดูเหมือนจะไม่นำเสนออะไรมากมายเกินกว่าที่ทำคะแนนและอธิบายไว้ในคำตอบก่อนหน้า 17 ข้อ ทั้งคำเตือนความครอบคลุมและการคัดค้านได้มีการหารือกันที่นั่นแล้ว
ริ้น

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