ฉันจะหลีกเลี่ยงการเขียนฟังก์ชัน pass-through มากมายใน wrapper ได้อย่างไร


13

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

ลองทำตัวอย่าง:

      Car
     /   \
Volvo     VolvoWithTrailer

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

int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}

วิธีที่ชัดเจนในการแก้ไขปัญหานี้คือการทำให้ VolvoWithTrailer เป็น subclass ของ Volvo

    Car
     |
   Volvo
     |
VolvoWithTrailer

แต่ดูเหมือนว่าจะละเมิดหลักการของการสนับสนุนการแต่งมากกว่ามรดก

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


2
ถึงกระนั้นก็ยังไม่ออกมากนักและคิดใน Java แล้วอินเทอร์เฟซ 'Trailer' คืออะไร VolvoWithTrailer จะขยาย Volvo และใช้ส่วนต่อประสาน Trailer หรือไม่

7
ชอบองค์ประกอบมากกว่ามรดกเฉพาะเมื่อมันทำให้รู้สึก
Robert Harvey

@RobertHarvey: +1 นั่นเป็นแนวทางไม่ใช่ "หลักการ" และไม่ใช่บัญญัติแน่นอน
Mason Wheeler

ใน Python คุณสามารถแก้ปัญหานี้ได้ด้วยการวิปัสสนา (สิ่งที่การสะท้อนของ C # calls)
user16764

1
IDE ของคุณไม่จัดการกับการสร้างรหัสหรือไม่
Amy Blankenship

คำตอบ:


5

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

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

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

2. มีสามประเภท (Car, Trailer, CarWithTrailer) ในส่วนของรหัสที่นักพัฒนาเข้าไปบ่อยหรือดูเหมือนจะเป็นเช่นนั้นหรือไม่?
ถ้าเป็นเช่นนั้นให้ระวังเพราะการเลือกสิ่งที่ผิดสามารถตัดค่าใช้จ่ายได้มากทุกครั้งที่สัมผัสรหัส หากไม่เป็นเช่นนั้นอาจไม่สร้างความแตกต่างในสิ่งที่คุณตัดสินใจ เพียงแค่เลือกทิศทางและไปกับมัน

3. มีอะไรที่เข้าใจง่ายที่สุด?
มีวิธีใดบ้างที่คุณคิดว่ามีใครบางคนเข้ามาข้างหลังคุณในทันทีจะ "รับ" สิ่งที่คุณพยายามจะทำ? เพื่อนร่วมทีมของคุณมีอคติเฉพาะที่อาจทำให้วิธีการหนึ่งยากขึ้นสำหรับพวกเขาในการรักษาหรือไม่? หากทุกสิ่งเท่ากันให้เลือกวิธีแก้ปัญหาที่กำหนดภาระการรับรู้ต่ำที่สุด

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

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

อาจมีข้อดีที่แตกต่างที่คุณจะได้รับฟรีโดยใช้วิธีการขยาย แต่ฉันไม่เห็นพวกเขา

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

ฉันไม่ใช่โปรแกรมเมอร์ C ++ ดังนั้นฉันจึงไม่รู้ว่าเครื่องมือการสร้างรหัสใดที่มีให้สำหรับคุณ IDE ที่ฉันใช้สามารถสร้างวิธีการจากอินเทอร์เฟซและฉันสามารถเพิ่มแม่แบบรหัสที่จะทำให้การเขียน pass-throughs ไม่เจ็บปวด หากคุณไม่สามารถเข้าถึง IDE ที่ทำสิ่งนี้ได้คุณสามารถปล่อยให้Excel เขียนโค้ดให้คุณได้


3

เนื่องจากอินเตอร์เฟสประเภทฐานมีขนาดค่อนข้างใหญ่จึงเกี่ยวข้องกับการเขียนฟังก์ชั่นการส่งผ่านจำนวนมาก

และมีปัญหาของคุณ

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


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