คุณมีบทคัดย่อ / ชั้นเรียนว่างเปล่าได้ไหม


10

แน่นอนคุณทำได้ฉันแค่สงสัยว่ามันมีเหตุผลในการออกแบบในลักษณะนี้

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

GameObject -> ชั้นฐาน (ประกอบด้วยสมาชิกข้อมูลเช่นชดเชย X และ Y และเวกเตอร์ของ SDL_Surface * a

MovableObject: GameObject -> ระดับนามธรรม + ชั้นเรียนมาของ GameObject (วิธีหนึ่งย้ายเป็นโมฆะ () = 0;)

NonMovableObject: GameObject -> คลาสที่ว่างเปล่า ... ไม่มีเมธอดหรือสมาชิกข้อมูลอื่นนอกจากตัวสร้างและ destructor (อย่างน้อยตอนนี้หรือไม่)

ต่อมาฉันวางแผนที่จะรับคลาสจาก NonMovableObject เช่น Tileset: NonMovableObject ฉันแค่สงสัยว่าคลาสนามธรรม "ว่างเปล่า" หรือแค่คลาสว่างมักใช้ ... ฉันสังเกตว่าวิธีที่ฉันทำเช่นนี้ฉันแค่สร้างคลาส NonMovableObject เพื่อประโยชน์ในการจัดหมวดหมู่

ฉันรู้ว่าฉันคิดมากสิ่งต่าง ๆ เพียงเพื่อทำการโคลน breakout แต่โฟกัสของฉันจะน้อยกว่าในเกมและเพิ่มเติมเกี่ยวกับการใช้การสืบทอดและการออกแบบเฟรมเวิร์กของเกม

คำตอบ:


2

ใน C ++ คุณมีการสืบทอดหลายแบบดังนั้นจึงไม่มีประโยชน์ที่จะมีคลาสที่ว่างเปล่าเหล่านั้น หากคุณต้องการให้ Ball สืบทอดมาจาก GameObject และ MovableObject ในภายหลัง (เช่นคุณต้องการเก็บอาร์เรย์ GameObjects และเรียกใช้วิธีการทำเครื่องหมายทุก ๆ วินาทีเพื่อให้ย้ายได้) มันง่ายพอที่จะทำ

แต่ในสถานการณ์ที่ผมจะแนะนำให้บุคคลที่คุณต้องจดจำความจริง " ต้องการองค์ประกอบ (encapsulation) มรดก " แทนและดูที่รูปแบบของรัฐ หากคุณต้องการให้แต่ละวัตถุมีสถานะการเคลื่อนไหวในภายหลังให้ส่งผ่านไปยัง GameObject ตัวอย่างเช่น: DiagonalBouncingMovementState สำหรับลูก HoriazontalControlledMovementState สำหรับไม้พาย NoMovementState สำหรับอิฐ

1) สิ่งนี้จะทำให้ง่ายขึ้นสำหรับคุณที่จะเขียนการทดสอบหน่วยถ้าคุณเลือกที่จะ (ซึ่งอีกครั้งฉันอยากจะแนะนำ) - เพราะคุณสามารถทดสอบ GameObject และแต่ละรัฐของคุณได้อย่างอิสระ

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

3) สิ่งที่สำคัญที่สุด: เมื่อคุณต้องการเริ่มการเปลี่ยนแปลงในเกมว่าลูกและ / หรือการเคลื่อนที่ของพายบนพื้นฐานของโทเค็นเหล่านั้นคุณเพียงแค่เปลี่ยนสถานะการเคลื่อนไหวของมัน (DiagonalMovementState กลายเป็น DiagonalWithGravityMovementState)

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

$ 0.02


8

ใน Java อินเทอร์เฟซ "empty" ถูกใช้เป็นตัวทำเครื่องหมาย (เช่น Serializable) เนื่องจาก ณ เวลารันไทม์วัตถุสามารถถูกตรวจสอบได้ไม่ว่าพวกเขาจะ "ใช้" อินเตอร์เฟสนั้นหรือไม่ก็ตาม แต่ใน C ++ ดูเหมือนว่าฉันไม่มีจุดหมายเลย

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


3

คุณไม่ได้คิดมาก คุณกำลังคิดและนั่นเป็นสิ่งที่ดี

ตามที่ระบุไว้แล้วอย่าใช้คุณสมบัติภาษาเพียงเพราะมี คุณลักษณะการเรียนรู้ภาษาการแลกเปลี่ยนเป็นกุญแจสำคัญในการออกแบบที่ดี

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

ลองเขียน abstractions ล้วนๆเพื่อกำหนดสัญญาของวัตถุของคุณ สัญญาวัตถุของคุณเป็นส่วนต่อประสานภายนอก ส่วนต่อประสานสาธารณะ มันทำอะไร

หมายเหตุ:มันเป็นสิ่งสำคัญที่จะเข้าใจในเรื่องนี้คือไม่ว่าข้อมูลมันมีx, แต่สิ่งที่มันไม่ymove()

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

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

โดยธรรมชาติแล้วNonMovableObjectมันไม่ได้ขยับ ใช้xและควรแน่นอนที่สุดได้รับการประกาศy constโดยธรรมชาติของมันMoveableObjectต้องการที่จะย้าย มันไม่สามารถประกาศของมันxและเป็นy constดังนั้นนี่ไม่ใช่ข้อมูลเดียวกันและไม่สามารถแชร์ได้

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

อาจจะไม่มีNonMovableObjectเลย สิ่งที่เป็นนามธรรมที่บริสุทธิ์GameObjectBaseที่กำหนดmove()วิธีการหรือไม่ ระบบของคุณGameObjectจะทำการติดตั้งmove()และระบบจะย้ายเฉพาะสิ่งที่ต้องการย้ายเท่านั้น

นี่เป็นเพียงจุดเริ่มต้น; รสชาติ หลุมกระต่ายลึกลงไปมาก ไม่มีช้อน.


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

2

มันมีแอปพลิเคชันใน C # เช่น ammoQ ที่กล่าวถึง แต่ใน C ++ แอปพลิเคชันเดียวจะเป็นถ้าคุณต้องการมีรายการพอยน์เตอร์ NonMovableObject

แต่จากนั้นฉันจะจินตนาการว่าคุณกำลังทำลายวัตถุผ่านตัวชี้ NonMoveableObject ซึ่งในกรณีนี้คุณจำเป็นต้องมี destructors เสมือนจริงและมันจะไม่เป็นคลาสที่ว่างเปล่าอีกต่อไป :)


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

ใช่มันเป็นจุดที่ดี
tenpn

1

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

เช่นคุณต้องการให้คอลเลกชันถือ Cats and Dogs ในการออกแบบของคุณคุณตัดสินใจว่าพวกเขามีจำนวนมากเหมือนกันดังนั้นจึงมีคลาสฐานของ Mamal และใช้ประเภทนี้ในคอลเลกชันของคุณ (เช่นรายการ) ทั้งหมดดี. จากนั้นคุณตัดสินใจว่าคุณต้องการเพิ่มกบในคอลเลกชันของคุณ แต่พวกเขาไม่ใช่ mamals ดังนั้นวิธีหนึ่งในการทำเช่นนี้คือการทำให้คลาสย่อยของ Frogs และ Mamals ของสัตว์ แต่บางทีคุณอาจไม่สามารถนึกถึงกบและ Mamals ได้ สัตว์เลี้ยงจึงว่างเปล่า จากนั้นคุณพิมพ์คอลเลกชันของคุณกับสัตว์แทน Mamal และทุกอย่างเป็นไปด้วยดี

ในชีวิตจริงฉันพบว่าแม้ว่าฉันจะสร้างคลาสฐานที่ว่างเปล่าไม่ช้าก็เร็วฟังก์ชั่นบางอย่างก็จะจบลงที่นั่น แต่ก็มีบางครั้งที่มันมีอยู่


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