วิธีลบรหัสที่ซ้ำกัน (โดยทั่วไป)


10

ในภาษา OO (เช่น แต่ไม่ จำกัด เฉพาะ Java) คุณจะแก้ไขโค้ดที่ซ้ำกันอย่างไรโดยขึ้นอยู่กับขอบเขตของการเกิดขึ้น ฉันจะเริ่มต้นด้วย (ตัวอย่าง)

  • ในคลาสเดียวกัน (ขอบเขต) ทำการแยกวิธีการแตกไฟล์ (แก้ไข)
  • ในชั้นเรียนของลำดับชั้นเดียวกัน (ขอบเขต) ดำเนินการวิธีการแยกและดึงขึ้น (แก้ไข)
  • ...

ดูตัวอย่างสำหรับการใช้หลักการ DRY (อย่าพูดซ้ำตัวเอง) กับคลาสเดียวกันนี้: geekswithblogs.net/chrisfalter/archive/2008/03/07/ …
NoChance

คำถามเดิมที่ SO ( stackoverflow.com/questions/7380946/… ) ถูกปิด ดังนั้นฉันจึงย้ายที่นี่
Peter Kofler

คำตอบ:


8

เมื่อเร็ว ๆ นี้ฉันพบคำตอบที่ดีสำหรับคำถามของฉันใน "รหัสสะอาด" ของลุงบ๊อบซึ่งฉันต้องการแบ่งปัน เขาแยกความซ้ำซ้อนสามประเภท

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

  • ในวิธีการเดียวกันให้ดำเนินการ Extract Local Variable และนำมาใช้ซ้ำ
  • ในคลาสเดียวกันให้ดำเนินการ refactoring วิธีการแยก
  • ในชั้นเรียนของวิธีการแยกลำดับชั้นเดียวกันและดึงมันขึ้นมา ลำดับชั้นอาจถูกสร้างขึ้นเพื่อค้นหาสถานที่สำหรับวิธีการ
  • ในชั้นเรียนของลำดับชั้นแยกใช้การมอบหมายให้วัตถุใหม่
  • หากเมธอดไม่ต้องการสถานะการปิดล้อมใด ๆ รูปแบบ "lib" อาจถูกนำไปใช้ (นั่นคือคอนเทนเนอร์สำหรับเมธอดแบบสแตติกซึ่งมักเรียกว่าSthUtilหรือSthLib)

กรณีของswitch/caseและif/elseที่มักจะทดสอบชุดเงื่อนไขเดียวกัน

  • เหล่านี้ควรถูกแทนที่ด้วย polymorphism

โมดูลที่ใช้อัลกอริทึมที่คล้ายกัน สิ่งเหล่านี้หายากที่สุดเนื่องจากไม่มีเครื่องตรวจจับโคลนที่สามารถค้นหาได้

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

นอกจากนี้ยังเป็นจุดที่ถูกต้องซึ่งถูกกล่าวถึงโดย Oded เมื่อจัดการกับไลบรารีเวอร์ชันต่าง ๆ

  • รวมในรุ่นเดียว รูปแบบการออกแบบซุ้มอาจช่วยได้ที่นี่

ในที่สุดประโยคที่ดีที่สุดที่จะตอบคำถามของฉันคือโดยการกระตุ้น:

วิธีการใช้รหัสซ้ำที่ใช้ในภาษา OO คือวัตถุ


5

โดยทั่วไป - รวมรหัสที่ซ้ำกันไว้ในที่เดียวและตรวจสอบให้แน่ใจว่าไซต์ที่ซ้ำซ้อนเดิมเรียกสถานที่รวม

ในตัวอย่างของคุณภายในคลาสนี้จะเป็นวิธีการแยกและภายในชุดชั้นเรียนวิธีการดึงขึ้นภายในชั้นฐาน

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

เมื่อจัดการกับไลบรารี่รุ่นต่าง ๆ ให้รวบรวมเป็นเวอร์ชั่นเดียว (ถ้าเป็นไปได้)


มันจะไม่ใช่วิธี "แบบดึงลง" หรือไม่ถ้าอยู่ในคลาสพื้นฐาน ฉันมักจะจินตนาการว่าคลาสพื้นฐานเป็นร่างกายภายใต้คลาสที่ได้รับมา
Dave Nay

ชื่อที่ถูกต้องจากหนังสือ Refactoring คือ "pull up"
Peter Kofler

1

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

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

แม้ว่านี่จะเป็นสิ่งที่ถกเถียงกันมาก แต่โพสต์นี้ยังพิจารณาถึงกรณีที่คุณต้องทนต่อโค้ดซ้ำ


1
+1 เกี่ยวกับ "กฎสามข้อ" ฉันประหลาดใจอยู่เสมอว่ามันใช้งานได้ในวงกว้างอย่างไร
Andy mango

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