คำถามติดแท็ก composition

14
แนวคิดเรื่อง“ องค์ประกอบของความโปรดปรานเหนือมรดก” นี้มาจากไหน?
ในช่วงไม่กี่เดือนที่ผ่านมามนต์ "องค์ประกอบที่เป็นที่โปรดปรานเหนือมรดก" ดูเหมือนจะเด้งขึ้นมาจากที่ไหนเลยและกลายเป็นเกือบ meme บางอย่างภายในชุมชนการเขียนโปรแกรม และทุกครั้งที่ฉันเห็นฉันก็รู้สึกงงเล็กน้อย มันเหมือนมีคนพูดว่า "ชอบการฝึกฝนมากกว่าค้อน" จากประสบการณ์ของฉันการจัดองค์ประกอบและการรับมรดกเป็นเครื่องมือสองแบบที่แตกต่างกันกับกรณีการใช้งานที่แตกต่างกันและจัดการกับมันราวกับว่าพวกมันใช้แทนกันได้และอีกอันหนึ่งเหนือกว่าอีกอันหนึ่ง นอกจากนี้ฉันไม่เคยเห็นคำอธิบายที่แท้จริงว่าทำไมการรับมรดกจึงไม่ดีและการจัดองค์ประกอบเป็นสิ่งที่ดีซึ่งทำให้ฉันสงสัยมากขึ้น ควรที่จะได้รับการยอมรับในความเชื่อหรือไม่? การทดแทน Liskov และ polymorphism นั้นเป็นที่รู้จักกันดีผลประโยชน์ที่ชัดเจนและ IMO ประกอบด้วยจุดทั้งหมดของการใช้การเขียนโปรแกรมเชิงวัตถุและไม่มีใครอธิบายได้ว่าทำไมพวกเขาจึงควรทิ้งองค์ประกอบเหล่านั้น ไม่มีใครรู้ว่าแนวคิดนี้มาจากไหนและเหตุผลที่อยู่เบื้องหลังมันคืออะไร?

5
ทำไมฉันถึงชอบการแต่งมากกว่าการสืบทอด?
ฉันมักจะอ่านองค์ประกอบที่เป็นที่ต้องการมากกว่าการสืบทอด บล็อกโพสต์เมื่อวันที่แตกต่างจากชนิดตัวอย่างเช่นสนับสนุนการใช้องค์ประกอบมรดก แต่ฉันไม่สามารถดูวิธีการแตกต่างคือความสำเร็จ แต่ฉันมีความรู้สึกว่าเมื่อผู้คนพูดว่าชอบการแต่งเพลงพวกเขาหมายถึงการผสมผสานระหว่างการผสมผสานกับการใช้อินเตอร์เฟส คุณจะได้รับความหลากหลายโดยไม่มีการสืบทอดได้อย่างไร นี่คือตัวอย่างที่เป็นรูปธรรมที่ฉันใช้การสืบทอด สิ่งนี้จะถูกเปลี่ยนเป็นใช้การเรียงลำดับอย่างไร Class Shape { string name; public: void getName(); virtual void draw()=0; } Class Circle: public Shape { void draw(/*draw circle*/); }

3
"การรวมตัวกับการสืบทอด" ละเมิด "หลักการที่แห้ง" หรือไม่?
ตัวอย่างเช่นลองพิจารณาฉันมีคลาสสำหรับคลาสอื่นเพื่อขยาย: public class LoginPage { public String userId; public String session; public boolean checkSessionValid() { } } และคลาสย่อยบางส่วน: public class HomePage extends LoginPage { } public class EditInfoPage extends LoginPage { } ในความเป็นจริง subclass ไม่มีวิธีการใด ๆ ที่จะแทนที่ฉันจะไม่เข้าถึง HomePage ด้วยวิธีทั่วไปเช่น: ฉันจะไม่ทำสิ่งที่ชอบ: for (int i = 0; i < loginPages.length; i++) { …

5
การกำหนดว่าวิธีใดสามารถแทนที่ข้อผูกพันที่แข็งแกร่งกว่าการกำหนดวิธีการที่สามารถเรียกได้
จาก: http://www.artima.com/lejava/articles/designprinciples4.html Erich Gamma: ฉันยังคงคิดว่ามันเป็นความจริงแม้หลังจากผ่านไปสิบปี การสืบทอดเป็นวิธีที่ยอดเยี่ยมในการเปลี่ยนพฤติกรรม แต่เรารู้ว่ามันเปราะบางเนื่องจากคลาสย่อยสามารถตั้งสมมติฐานเกี่ยวกับบริบทที่มีการเรียกเมธอดแทนที่ได้ง่าย มีการเชื่อมต่ออย่างแน่นหนาระหว่างคลาสฐานและคลาสย่อยเนื่องจากบริบทโดยปริยายซึ่งโค้ดคลาสย่อยที่ฉันเสียบเข้าจะถูกเรียก องค์ประกอบมีคุณสมบัติที่ดีกว่า การมีเพศสัมพันธ์จะลดลงเพียงแค่มีสิ่งเล็ก ๆ ที่คุณเสียบเข้าไปกับสิ่งที่ใหญ่กว่าและวัตถุที่ใหญ่กว่าก็เรียกวัตถุที่เล็กกว่ากลับมา จากมุมมองของ API ที่กำหนดว่าวิธีการใด ๆ ที่สามารถแทนที่ได้คือความมุ่งมั่นที่แข็งแกร่งกว่าการกำหนดวิธีการที่สามารถเรียกได้ ฉันไม่เข้าใจสิ่งที่เขาหมายถึง ใครช่วยอธิบายหน่อยได้ไหม

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

8
“ ชอบการแต่งเพลงมากกว่ามรดก” - เป็นเหตุผลเดียวที่จะป้องกันการเปลี่ยนแปลงลายเซ็นได้หรือไม่?
หน้านี้สนับสนุนการแต่งเพลงมากกว่าการสืบทอดด้วยอาร์กิวเมนต์ต่อไปนี้ (ใช้ถ้อยคำใหม่ในคำพูดของฉัน): การเปลี่ยนแปลงในลายเซ็นของวิธีการของซูเปอร์คลาส (ซึ่งไม่ได้ถูกแทนที่ในคลาสย่อย) ทำให้เกิดการเปลี่ยนแปลงเพิ่มเติมในหลาย ๆ สถานที่เมื่อเราใช้การสืบทอด อย่างไรก็ตามเมื่อเราใช้ Composition การเปลี่ยนแปลงเพิ่มเติมที่จำเป็นนั้นมีอยู่ในที่เดียวนั่นคือคลาสย่อย นั่นเป็นเหตุผลเดียวที่จะสนับสนุนการแต่งเพลงมากกว่าการสืบทอด? เพราะถ้าเป็นกรณีนี้ปัญหานี้สามารถบรรเทาได้ง่ายโดยบังคับใช้รูปแบบการเข้ารหัสที่สนับสนุนการเอาชนะวิธีการทั้งหมดของ superclass แม้ว่า subclass จะไม่เปลี่ยนการใช้งาน (นั่นคือการใส่ dummy แทนที่ใน subclass) ฉันทำอะไรบางอย่างหายไปหรือเปล่า

2
ฉันจะหลีกเลี่ยงการเขียนฟังก์ชัน pass-through มากมายใน wrapper ได้อย่างไร
ฉันมีคลาสซึ่งล้อมคลาสอื่นที่เป็นประเภทพื้นฐานทั่วไป เนื่องจากอินเตอร์เฟสประเภทฐานมีขนาดค่อนข้างใหญ่จึงเกี่ยวข้องกับการเขียนฟังก์ชั่นการส่งผ่านจำนวนมาก ฉันกำลังมองหาวิธีที่จะหลีกเลี่ยงปัญหานี้ ลองทำตัวอย่าง: Car / \ Volvo VolvoWithTrailer ตอนนี้ฉันต้องติดตั้งฟังก์ชั่นแต่ละอย่างในอินเทอร์เฟซสำหรับรถยนต์ของ VolvoWithTrailer และเรียกใช้ฟังก์ชั่นที่เหมาะสมบนวัตถุที่ห่อหุ้มวอลโว่ยกเว้นอาจ GetMaxSpeed ​​() ซึ่งจะคืนสิ่งที่ต่ำกว่า โดยทั่วไปฉันจะมีฟังก์ชั่นมากมายเช่น int VolvoWithTrailer::GetNumSeats() { return mVolvo.GetNumSeats() } วิธีที่ชัดเจนในการแก้ไขปัญหานี้คือการทำให้ VolvoWithTrailer เป็น subclass ของ Volvo Car | Volvo | VolvoWithTrailer แต่ดูเหมือนว่าจะละเมิดหลักการของการสนับสนุนการแต่งมากกว่ามรดก ฉันจะหลีกเลี่ยงการเขียนโปรแกรมเสริมเหล่านี้ได้อย่างไร (ภาษาคือ C ++) หรือ - ถ้านั่นคือตำแหน่งของคุณ - ทำไมฉันต้องเขียนพวกเขา / แค่ใช้การสืบทอด? มีแม่แบบเวทย์มนตร์ที่สามารถช่วยได้หรือไม่?

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

3
องค์ประกอบมากกว่ามรดก แต่
ฉันพยายามสอนตัวเองเกี่ยวกับวิศวกรรมซอฟต์แวร์และการหาข้อมูลที่ขัดแย้งกันซึ่งทำให้ฉันสับสน ฉันได้เรียนรู้เกี่ยวกับ OOP และคลาสนามธรรม / อินเทอร์เฟซคืออะไรและใช้งานอย่างไร แต่จากนั้นฉันก็อ่านว่าควรจะ 'สนับสนุนองค์ประกอบเหนือมรดก' ฉันเข้าใจการจัดองค์ประกอบคือเมื่อคลาสหนึ่งประกอบ / สร้างวัตถุของคลาสอื่นเพื่อใช้ / โต้ตอบกับฟังก์ชันการทำงานของวัตถุใหม่นั้น ดังนั้นคำถามของฉันคือ ... ฉันควรจะไม่ใช้คลาสหรืออินเตอร์เฟสแบบนามธรรมหรือไม่? หากไม่ต้องการสร้างคลาสนามธรรมและขยาย / สืบทอดฟังก์ชันการทำงานของคลาสนามธรรมในคลาสที่เป็นรูปธรรมและแทนที่จะสร้างวัตถุใหม่เพื่อใช้ฟังก์ชันของคลาสอื่น หรือฉันควรใช้องค์ประกอบและสืบทอดจากคลาสนามธรรม; ใช้พวกเขาทั้งสองร่วมกัน? ถ้าเป็นเช่นนั้นคุณช่วยยกตัวอย่างว่ามันจะทำงานอย่างไรและมีประโยชน์อย่างไร เนื่องจากฉันคุ้นเคยกับ PHP มากที่สุดฉันจึงใช้มันเพื่อพัฒนาทักษะ OOP / SE ของฉันก่อนที่จะย้ายไปใช้ภาษาอื่นและถ่ายโอนทักษะ SE ที่เพิ่งได้รับมาดังนั้นตัวอย่างการใช้ PHP จะได้รับการชื่นชมมากที่สุด

4
การฉีดพึ่งพามือเป็นทางเลือกที่ดีกว่าในการจัดองค์ประกอบและความหลากหลาย?
ก่อนอื่นฉันเป็นโปรแกรมเมอร์ระดับต้น ในความเป็นจริงฉันกำลังจบระดับ AS ด้วยโปรเจ็กต์สุดท้ายของฤดูร้อน ในงานใหม่ของฉันเมื่อไม่มีโครงการให้ฉันทำ (พวกเขากำลังรอที่จะเติมทีมด้วยการจ้างงานใหม่) ฉันได้รับหนังสือให้อ่านและเรียนรู้จากในขณะที่ฉันรอ - ตำราบางเล่มอื่น ๆ ไม่มาก (เช่น Code Complete) หลังจากอ่านหนังสือเหล่านี้ฉันได้หันไปใช้อินเทอร์เน็ตเพื่อเรียนรู้ให้มากที่สุดและเริ่มเรียนรู้เกี่ยวกับ SOLID และ DI (เราได้พูดถึงหลักการทดแทนของ Liskov แต่ไม่ได้มีแนวคิด SOLID อื่น) เพื่อที่ฉันจะได้เรียนรู้ฉันนั่งลงเพื่อเรียนรู้ให้ดีขึ้นและเริ่มเขียนโค้ดเพื่อใช้ DI ด้วยมือ (ไม่มีกรอบ DI บนคอมพิวเตอร์การพัฒนา) สิ่งที่ฉันทำมันฉันสังเกตเห็นว่ามันรู้สึกคุ้นเคย ... และดูเหมือนว่ามันเป็นเหมือนงานที่ฉันเคยทำในอดีตโดยใช้องค์ประกอบของคลาสนามธรรมโดยใช้ polymorphism ฉันคิดถึงภาพที่ใหญ่กว่านี้หรือไม่? มีบางอย่างเกี่ยวกับ DI (อย่างน้อยด้วยมือ) ที่ไปได้หรือไม่? ฉันเข้าใจถึงความเป็นไปได้ของการกำหนดค่าที่ไม่ได้อยู่ในรหัสของกรอบงาน DI บางอันที่มีประโยชน์มากพอ ๆ กับการเปลี่ยนแปลงสิ่งต่าง ๆ โดยไม่ต้องคอมไพล์ใหม่ แต่เมื่อทำด้วยมือฉันไม่แน่ใจว่ามันแตกต่างจากที่ระบุข้างต้น ... ข้อมูลเชิงลึกเกี่ยวกับเรื่องนี้จะมีประโยชน์มาก!

2
เมื่อ Rob Pike พูดว่า“ Go เป็นเรื่องเกี่ยวกับการแต่งเพลง” เขาหมายถึงอะไรกันแน่? [ปิด]
ปิด คำถามนี้เป็นคำถามความคิดเห็นตาม ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบข้อเท็จจริงและการอ้างอิงได้โดยแก้ไขโพสต์นี้ ปิดให้บริการใน5 ปีที่ผ่านมา จากLess มีมากขึ้นแบบทวีคูณ ถ้า C ++ และ Java เกี่ยวกับลำดับชั้นของประเภทและอนุกรมวิธานของประเภท Go เป็นเรื่องเกี่ยวกับองค์ประกอบ

5
ฉันควรจะชอบองค์ประกอบหรือการสืบทอดในสถานการณ์นี้หรือไม่
พิจารณาอินเทอร์เฟซ: interface IWaveGenerator { SoundWave GenerateWave(double frequency, double lengthInSeconds); } อินเทอร์เฟซนี้ถูกใช้งานโดยคลาสที่สร้างคลื่นของรูปร่างที่แตกต่างกัน (ตัวอย่างเช่นSineWaveGeneratorและSquareWaveGenerator) ฉันต้องการใช้คลาสที่สร้างSoundWaveจากข้อมูลดนตรีไม่ใช่ข้อมูลเสียงดิบ มันจะได้รับชื่อของโน้ตและระยะเวลาในแง่ของการเต้น (ไม่กี่วินาที) ที่และภายในใช้IWaveGeneratorฟังก์ชั่นในการสร้างSoundWaveตาม คำถามคือควรNoteGeneratorประกอบด้วยIWaveGeneratorหรือควรได้รับมรดกจากการIWaveGeneratorดำเนินการ? ฉันเอนตัวไปยังองค์ประกอบเนื่องจากเหตุผลสองประการ: 1- มันช่วยให้ฉันสามารถฉีดใด ๆIWaveGeneratorไปยังNoteGeneratorแบบไดนามิก นอกจากนี้ฉันต้องการเพียงหนึ่งNoteGeneratorชั้นแทนSineNoteGenerator, SquareNoteGeneratorฯลฯ 2- มีความต้องการไม่ได้ที่จะเปิดเผยอินเตอร์เฟซในระดับต่ำกว่าที่กำหนดโดยNoteGeneratorIWaveGenerator อย่างไรก็ตามฉันโพสต์คำถามนี้เพื่อฟังความคิดเห็นอื่น ๆ เกี่ยวกับเรื่องนี้อาจเป็นจุดที่ฉันไม่ได้คิด BTW: ฉันจะบอกว่าNoteGenerator เป็นแนวคิดIWaveGeneratorเพราะมันสร้างSoundWaves

4
การลดสำเร็จรูปในชั้นเรียนที่ใช้ส่วนต่อประสานผ่านองค์ประกอบ
ฉันได้เรียน: Aว่าเป็นคอมโพสิตของจำนวนของชั้นเรียนขนาดเล็กB, และCD B, CและDใช้อินเตอร์เฟซIB, ICและIDตามลำดับ ตั้งแต่AรองรับทุกการทำงานของB, CและD, AการดำเนินการIB, ICและIDเช่นกัน แต่นี้โชคไม่ดีที่นำไปสู่การเป็นจำนวนมากเส้นทางใหม่ในการดำเนินการA ชอบมาก interface IB { int Foo {get;} } public class B : IB { public int Foo {get {return 5;}} } interface IC { void Bar(); } public class C : IC { public void Bar() { } } …

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

9
มรดกเทียบกับองค์ประกอบสำหรับชิ้นหมากรุก
การค้นหาอย่างรวดเร็วของ stackexchange นี้แสดงให้เห็นว่าในองค์ประกอบทั่วไปโดยทั่วไปถือว่ามีความยืดหยุ่นมากกว่าการสืบทอด แต่เช่นเคยขึ้นอยู่กับโครงการ ฯลฯ และมีหลายครั้งที่การสืบทอดเป็นตัวเลือกที่ดีกว่า ฉันต้องการสร้างเกมหมากรุกสามมิติที่แต่ละชิ้นมีตาข่ายอาจเป็นภาพเคลื่อนไหวที่แตกต่างกันไปเรื่อย ๆ ในตัวอย่างที่เป็นรูปธรรมนี้ดูเหมือนว่าคุณสามารถโต้แย้งกรณีสำหรับทั้งสองวิธีฉันผิดหรือเปล่า? การสืบทอดจะมีลักษณะเช่นนี้ (พร้อมตัวสร้างที่เหมาะสม ฯลฯ ) class BasePiece { virtual Squares GetValidMoveSquares() = 0; Mesh* mesh; // Other fields } class Pawn : public BasePiece { Squares GetValidMoveSquares() override; } ซึ่งแน่นอนว่าเป็นไปตามหลักการ "เป็น -a" ในขณะที่องค์ประกอบจะมีลักษณะเช่นนี้ class MovementComponent { virtual Squares GetValidMoveSquares() = 0; } …

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