การทำสำเนารหัสโดยไม่มีสิ่งใดที่ชัดเจน


14

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

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

คุณคิดว่าอะไรคือวิธีที่ดีที่สุดในการพูดถึงเรื่องนี้?

คำตอบ:


18

บางครั้งการทำสำเนารหัสเป็นผลมาจาก "pun": สองสิ่งดูเหมือนกัน แต่ไม่ใช่

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

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

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

วิธีที่คุณตอบคำถามนั้นอาจช่วยให้คุณเข้าใจถึงสิ่งที่เป็นนามธรรมได้ดีขึ้น

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

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

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


4

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

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


+1 สำหรับเทคนิคที่ยอดเยี่ยมจำนวนมากที่ถูกบีบอัดในพื้นที่ จำกัด (จะเป็น +1 สำหรับเทคนิคที่อธิบายด้วย)
Macneil

3

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


2

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

  • แทนที่จะสร้างฟังก์ชันใหม่หนึ่งเพื่อเก็บรหัสทั่วไปแบ่งการทำงานเป็นหลายส่วนที่แตกต่างกัน
  • จัดกลุ่มชิ้นส่วนเล็ก ๆ เข้าด้วยกันตามชนิดข้อมูลทั่วไปหรือพฤติกรรมที่เป็นนามธรรม
  • เขียนรหัสที่ซ้ำกันให้ชิ้นใหม่;
  • หากรหัสใหม่ยังคงท้าทาย abstraction ที่ชัดเจนให้แบ่งมันเป็นขนาดเล็กเช่นกันและทำซ้ำกระบวนการ

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

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

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