การบำรุงรักษารหัส: การรักษารูปแบบที่ไม่ดีเมื่อขยายรหัสใหม่เพื่อให้สอดคล้องกันหรือไม่?


45

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

ฉันควร:

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

หรือ

  • ลองใช้สิ่งที่ฉันรู้สึกดีขึ้นแม้ว่าจะมีการแนะนำรูปแบบอื่นในรหัสหรือไม่

Precison แก้ไขหลังจากคำตอบแรก:

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

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

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

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


คำถามที่น่าสนใจมาก!
ฟิลิปป์

1
การบำรุงรักษาโค้ดโง่ที่น่าเบื่อง่าย ๆ - โดยนิยามง่าย ฉันอยากมีชีวิตที่เรียบง่ายและออกเดินทาง แต่เช้าตรู่ทุกวัน
quick_now

ใช่ แต่ฉันขี้เกียจเกินไปที่จะทำรหัสโง่ที่น่าเบื่อ :) ฉันจะชอบทำงานหนักเป็นเวลา 2 หรือ 3 วันเพื่อสร้างบางสิ่งที่จะทำส่วนนี้ให้ฉัน!
Guillaume

1
เมื่อใดที่โง่หรือน่าเบื่อสับสนง่าย
Erik Reppen

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

คำตอบ:


42

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

โดยทั่วไปแล้วมีจุดมุ่งหมายเพื่อปรับปรุงรหัสเล็กน้อยทุกครั้งที่คุณสัมผัส ทำตามกฎ Boy Scout ( ประกาศเกียรติคุณโดย Robert C. Martin ) โดยออกรหัสทำความสะอาดกว่าที่คุณพบ เมื่อคุณเพิ่มรหัสใหม่ให้พยายามแยกออกจากรหัสเสียที่มีอยู่ เช่นไม่ฝังไว้ในวิธีการที่ยาว แต่เพิ่มการเรียกไปยังวิธีอื่นแล้วใส่รหัสใหม่ลงไป ด้วยวิธีนี้คุณจะขยายเกาะที่ใหญ่ขึ้นเรื่อย ๆ ของรหัสสะอาด (er) ภายใน codebase ที่มีอยู่

ปรับปรุง

ต้นทุนการปรับโครงสร้างจะหนักกว่าประโยชน์ของมัน [... ] คุณในฐานะนักพัฒนาคุณต้องการที่จะรักษารหัสที่น่าเบื่องี่เง่าที่ง่ายหรือจะมีผู้ช่วยบางอย่างที่จะทำโค้ดที่น่าเบื่อแบบโง่ ๆ ในที่ของคุณ?

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

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

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


7
มันง่ายมากที่จะตกหลุมพรางของ 'รหัสที่มีอยู่แล้วและอาจเป็นเช่นนั้นต่อไป ... ' โปรแกรมเมอร์ที่ดีอย่าทำเช่นนั้น คำตอบที่ดี
sevenseacat

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

2
@Steven ก็จะปรับให้ทุกอย่าง refactor ในครั้งเดียวถ้าคุณสามารถจ่ายได้ ในโครงการชีวิตจริงส่วนใหญ่คุณไม่สามารถหยุดทุกอย่างและใช้เวลาหลายวันหรือหลายสัปดาห์ติดต่อกันในการปรับโครงสร้าง แม้ว่าคุณจะโชคดีที่มีผู้จัดการที่ให้การสนับสนุนโครงการก็ยังคงต้องดำเนินต่อไป
PéterTörök

1
@Steven ขึ้นอยู่กับ - ดูการอัปเดตของฉันด้านบน
PéterTörök

1
@ PéterTörök: อัปเดตที่ดี! คำอธิบายที่สมบูรณ์แบบของปัจจัยในโลกแห่งความเป็นจริงที่จะต้องคำนึงถึง
Steven Jeuris

4

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


3

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

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


3

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

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

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


+1 "จากนั้นคุณมีสามวิธีในการทำสิ่งเดียวกัน" ฉันได้เห็นสิ่งนี้ในทุกโครงการขององค์กรที่ฉันทำงาน ฉันจะบอกว่าอย่าพยายาม refactor จนกว่าคุณจะ scoured รหัสเพื่อให้แน่ใจว่าไม่มีอีกส่วนของรหัสที่พยายามดูแลรหัสน่าเกลียดที่คุณตัดสินใจว่าคุณต้องการ refactor บางครั้งมันเป็นการดีที่สุดที่จะติดกับการประชุมสำเร็จรูปอย่างน้อยก็จนกว่าคุณจะได้รับรหัสอ่านอย่างละเอียด
TK-421

1

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

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

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

อัปเดตที่เกี่ยวข้องกับการตอบกลับของPéterTörök: ไม่ใช่เพราะการเลื่อนการเปลี่ยนสถานะ "เพราะใช้เวลา" เวลาในการปรับโครงสร้างอีกครั้งเพิ่มขึ้นในภายหลังหรือไม่ การปรับโครงสร้างไม่ควรใช้เวลานานเมื่อดำเนินการบ่อยขึ้น

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


1
"จะอธิบายให้เจ้านายของคุณทราบได้อย่างไรว่าคุณจะใช้เวลาสองสามวันในการเขียนโค้ดซึ่งไม่ได้เพิ่มอะไรเข้าไปในผลิตภัณฑ์นั้นเป็นเรื่องยากและเป็นคำถามที่แตกต่างอย่างสิ้นเชิง" ลองดี ;-) น่าเสียดายที่ในชีวิตจริงเราต้องแก้ปัญหานี้ด้วย นั่นเป็นเหตุผลว่าทำไมจึงใช้งานได้จริงในการก้าวเล็ก ๆ การรีแฟคเตอร์ครึ่งชั่วโมงสามารถทำได้โดยเป็นส่วนหนึ่งของงานสองชั่วโมงโดยที่ผู้จัดการของคุณไม่จำเป็นต้องรู้ OTOH ใช้เวลาสองวันเต็มในการปรับโครงสร้างการใช้งานไม่ค่อยมีใครสังเกตเห็น
PéterTörök

@ PéterTörök: ฉันได้อัปเดตโพสต์เล็กน้อย แน่นอนว่าคุณยังมีสถานการณ์ในโลกแห่งความเป็นจริงที่คุณไม่ได้รับอนุญาตให้ใช้เวลาในการปรับโครงสร้างใหม่ แต่ฉันเชื่ออย่างยิ่งว่าในทางทฤษฎีแล้วมันได้รับเวลาเสมอ (เว้นแต่คุณจะรู้รหัสที่คุณกำลังทำงานอยู่จะไม่ได้รับการสนับสนุนอีกต่อไปในอนาคตอันใกล้)
Steven Jeuris

ดังที่พวกเขากล่าวว่าในทางทฤษฎีไม่มีความแตกต่างระหว่างการฝึกฝนและทฤษฎีมากนัก อย่างไรก็ตามในทางปฏิบัติ ... :-) ในชีวิตจริงคุณอาจไม่ได้รับค่าใช้จ่ายในการเปลี่ยนสถานะ ฉันขยายคำตอบของฉันในเรื่องนี้
PéterTörök

1
การสร้างใหม่ซึ่งการลบรหัสที่ซ้ำกันนั้นไม่ดีเสมอไป อาจเป็นไปได้ว่าทั้งสองวิธีอาจเหมือนกันภายใต้กฎเกณฑ์ทางธุรกิจในปัจจุบัน แต่อาจไม่ใช่ในวันพรุ่งนี้ ตัวอย่างเช่นAcmeLockerBankหนึ่งอาจมีgetRow(int itemIndex)วิธีการที่ส่งกลับindex % 5และAcmeButtonPanelอาจมีวิธีการที่เหมือนกันเพราะทั้งตู้เก็บของและปุ่มแผงหมายเลขสิ่งต่าง ๆ ในลักษณะเดียวกัน; ถ้าไม่มีธนาคารตู้เก็บของในปัจจุบันที่มีรายการที่มีดัชนีมากกว่า 1,000 แต่แผงปุ่มบางปุ่มทำและตู้เก็บของในอนาคตใช้ระยะห่างแถวที่แตกต่างกันสำหรับดัชนีในช่วง 1,000-1,999 ...
supercat

1
... การเพิ่มพฤติกรรมเพิ่มเติมให้กับธนาคารตู้เก็บของจะเป็นเรื่องง่ายถ้าธนาคารตู้เก็บของและธนาคารปุ่มมีgetRowวิธีการที่แตกต่างกันแต่อาจจะยากขึ้นหากฟังก์ชั่นได้ถูกรวมเข้ากับวิธีการทั่วไป
supercat

0

คุณไม่สามารถสร้างอินเทอร์เฟซ / คลาสใหม่ที่ทำงานเป็น Facade ผ่านโค้ดเก่าในขณะที่แนะนำโค้ดใหม่ในสไตล์ของคุณเองที่สามารถขยายได้อย่างง่ายดาย?


0

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


0

คุณในฐานะนักพัฒนาคุณต้องการบำรุงรักษาโค้ดที่น่าเบื่องี่เง่าที่เรียบง่ายหรือมีผู้ช่วยบางคนที่จะทำโค้ดที่น่าเบื่องี่เง่าในที่ของคุณหรือไม่?

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

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

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

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