क्या आप "खाली" सार / कक्षाएं ले सकते हैं?


10

बेशक आप कर सकते हैं, मैं सोच रहा हूं कि क्या इस तरह से डिजाइन करना तर्कसंगत है।

मैं एक ब्रेकआउट क्लोन बना रहा हूं और कुछ क्लास डिजाइन कर रहा था। मैं विरासत का उपयोग करना चाहता था, भले ही मेरे पास सी ++ में मैंने जो सीखा है, उसे लागू करने के लिए नहीं है। मैं वर्ग डिजाइन के बारे में सोच रहा था और कुछ इस तरह से आया:

GameObject -> बेस क्लास (जिसमें x और y

ऑफ़सेट्स जैसे डेटा मेंबर होते हैं, और SDL_Surface * MovableObject का वेक्टर होता है: GameObject -> एब्स्ट्रैक्ट क्लास + गेमऑब्जेक्ट का क्लास व्युत्पन्न (एक विधि शून्य चाल () = 0;)

NonMovableObject: GameObject -> खाली वर्ग ... कंस्ट्रक्टर और विध्वंसक (अभी कम से कम?) के अलावा कोई विधियाँ या डेटा सदस्य नहीं।

बाद में मैं NonMovableObject से एक वर्ग प्राप्त करने की योजना बना रहा था, जैसे टाइलसेट: NonMovableObject। मैं सोच रहा था कि क्या "खाली" अमूर्त कक्षाएं या सिर्फ खाली कक्षाएं अक्सर उपयोग की जाती हैं ... मुझे लगता है कि जिस तरह से मैं यह कर रहा हूं, मैं सिर्फ वर्गीकरण के लिए नॉनवेजेबल ऑबजेक्ट बना रहा हूं।

मुझे पता है कि मैं केवल एक ब्रेकआउट क्लोन बनाने के लिए चीजों को खत्म कर रहा हूं, लेकिन मेरा ध्यान खेल पर कम और विरासत का उपयोग करने और कुछ प्रकार के गेम ढांचे को डिजाइन करने पर है।

जवाबों:


2

C ++ में आपके पास एक से अधिक इनहेरिटेंस हैं इसलिए उन खाली कक्षाओं के होने का शाब्दिक कोई लाभ नहीं है। यदि आप बाद में GameObject और MovableObject से बॉल इनहेरिट करना चाहते हैं (उदाहरण के लिए, उदाहरण के लिए, आप GameObjects की एक सरणी को पकड़ना चाहते हैं और उन सभी को स्थानांतरित करने के लिए एक टिक विधि को हर सेकंड में कॉल करते हैं), जो करना काफी आसान है।

लेकिन, उस स्थिति में, मैं व्यक्तिगत रूप से सुझाव दूंगा कि आप याद रखें कि स्वयंसिद्ध " वंशानुक्रम पर रचना (पसंद) को प्राथमिकता दें " के बजाय और राज्य पैटर्न को देखें । यदि आप चाहते हैं कि प्रत्येक ऑब्जेक्ट को बाद में अपनी गति की स्थिति मिले, तो इसे गेमऑबजेक्ट में पास करें। उदाहरण के लिए: गेंद के लिए DiagonalBouncingMovementState, पैडल के लिए HoriazontalControlledMovementState, एक ईंट के लिए NoMovementState।

1) इससे आपको यूनिट टेस्ट लिखने में आसानी होगी , यदि आप चुनते हैं (जो, फिर से, मैं सुझाऊंगा) - क्योंकि आप गेमऑबजेक्ट और आपके प्रत्येक राज्य का स्वतंत्र रूप से परीक्षण कर सकते हैं।

2) कहो कि आपके पास ईंटों से गिरने वाले टोकन हैं, लेकिन फिर आप उनमें से एक को बदलना चाहते हैं ताकि वे तिरछे तरीके से आगे बढ़ें - बजाय इसे वर्ग विरासत के कुछ जटिल पदानुक्रम के आसपास स्थानांतरित करने के बजाय, आप बस हार्डकोर आंदोलन की स्थिति को बदल सकते हैं जो इसे पारित हो जाता है ।

3) सबसे महत्वपूर्ण बात: जब आप इन-गेम को बदलना शुरू करना चाहते हैं , तो उन टोकनों के आधार पर गेंद और / या पैडल कैसे चलते हैं, तो आप बस इसकी गति स्थिति को बदलते रहते हैं (DiagonalMovementState DiagonalWithGravityMoveMestState)।

अब, इस में से कोई भी सुझाव नहीं था कि विरासत हमेशा खराब होती है, बस यह प्रदर्शित करने के लिए कि हम विरासत पर इनकैप्सुलेशन क्यों पसंद करते हैं। आप अभी भी GameObject से प्रत्येक प्रकार के ऑब्जेक्ट को प्राप्त कर सकते हैं और उन वर्गों को उनके प्रारंभिक आंदोलन राज्य को समझ सकते हैं। आप लगभग निश्चित रूप से अपने प्रत्येक मूवमेंट स्टेट्स को एक अमूर्त मूवमेंटस्टैट क्लास से प्राप्त करना चाहेंगे क्योंकि C ++ में इंटरफेस नहीं है।

$ 0.02


8

जावा में, "खाली" इंटरफेस का उपयोग मार्कर के रूप में किया जाता है (उदाहरण के लिए सीरियल करने योग्य), क्योंकि रनटाइम पर, वस्तुओं को जाँचा जा सकता है या वे उस इंटरफ़ेस को "लागू" नहीं कर सकते हैं; लेकिन C ++ में, यह मेरे लिए बहुत व्यर्थ लगता है।

आईएमओ, भाषा सुविधाओं को उपकरण माना जाना चाहिए, कुछ ऐसा जो आपको कुछ लक्ष्यों तक पहुंचने में मदद करता है, न कि दायित्वों के लिए। सिर्फ इसलिए कि आप एक सुविधा का उपयोग कर सकते हैं इसका मतलब यह नहीं है कि आपके पास है । अर्थहीन विरासत एक कार्यक्रम को बेहतर नहीं बनाती है।


3

आप यह सोचकर खत्म नहीं हुए हैं; आप सोच रहे हैं और यह अच्छा है।

जैसा कि पहले ही कहा जा चुका है, भाषा की सुविधा का उपयोग सिर्फ इसलिए नहीं करें क्योंकि यह वहां है। लर्निंग लैंग्वेज फीचर ट्रेडऑफ अच्छे डिजाइन की कुंजी है।

वर्गीकरण के लिए किसी को आधार वर्ग का उपयोग नहीं करना चाहिए। यह जाँच प्रकार को फंसा सकता है। यह एक बुरा विचार है।

शुद्ध अमूर्त लिखने पर विचार करें जो आपकी वस्तुओं के अनुबंध को परिभाषित करता है। आपकी वस्तुओं का अनुबंध आउटवर्ड फेसिंग इंटरफ़ेस है। इसका सार्वजनिक इंटरफ़ेस। यह क्या करता है।

नोट: यह समझना महत्वपूर्ण है यह महत्वपूर्ण है कि उसे किस डेटा है x, yलेकिन क्या यह करता है move()

आपके डिजाइन में, आपके पास एक वर्ग है GameObject। आप इसके डेटा के लिए इस पर निर्भर हैं और इसकी कार्यक्षमता के लिए नहीं। यह महसूस करता है कुशल और साझा करने के लिए क्या आम साझा डेटा की तरह लगता है आपके मामले में, के लिए विरासत का उपयोग करने के लिए सही xऔर y

यह वंशानुक्रम का सही उपयोग नहीं है। हमेशा याद रखें, वंशानुक्रम युग्मन का सबसे कठोर रूप है जो आपके पास संभवतः हो सकता है और आपको हर समय ढीले युग्मन के लिए प्रयास करना चाहिए।

अपने स्वभाव NonMovableObjectसे नहीं चलता है। इसका xऔर yनिश्चित रूप से घोषित किया जाना चाहिए const। इसके स्वभाव से बहुत MoveableObjectआगे बढ़ने की जरूरत है। यह घोषणा नहीं कर सकते हैं अपनी xऔर yके रूप में const। इस प्रकार, यह समान डेटा नहीं है और इसे साझा नहीं किया जा सकता है।

अपनी वस्तुओं की कार्यक्षमता, या अनुबंध पर विचार करें। वे क्या करना चाहिए करना ? सही हो जाओ और डेटा आ जाएगा। एक समय में एक वस्तु पर काम करें। बदले में प्रत्येक के बारे में चिंता। आप पाएंगे कि आपके अच्छे डिजाइन पुन: प्रयोज्य हैं।

शायद वहाँ बिल्कुल नहीं है NonMovableObject। एक शुद्ध अमूर्तता के बारे में क्या है GameObjectBaseजो एक move()विधि को परिभाषित करता है ? आपका सिस्टम इंस्टेंस करता है GameObjectजो लागू होता है move()और सिस्टम केवल उन्हीं को स्थानांतरित करता है जिन्हें स्थानांतरित करने की आवश्यकता होती है।

यह सिर्फ शुरुआत है; एक स्वाद। खरगोश का छेद ज्यादा गहरा हो जाता है। कोई चम्मच नहीं है।


हालांकि यह सच है कि न तो MovableObjectहै और न ही NonMovableObjectएक दूसरे से वारिस कर सकते हैं, वे दोनों एक स्थान है, जैसे, वे दोनों को कोड के द्वारा उपभोग्य होना चाहिए जो उदाहरण के लिए किसी वस्तु की ओर एक राक्षस के उद्देश्य को निर्देशित करना चाहता है बिना इस बात के कि वह वस्तु आगे बढ़ सकती है या नहीं।
सुपरकैट

2

इसमें C # में दिए गए एप्लिकेशन जैसे कि बारूद का उल्लेख है, लेकिन C ++ में केवल वही एप्लिकेशन होगा यदि आप नॉनमोबल ओब्जेक्ट पॉइंटर्स की सूची बनाना चाहते हैं।

लेकिन तब मुझे लगता है कि आप NonMoveableObject पॉइंटर के माध्यम से ऑब्जेक्ट्स को नष्ट कर रहे होंगे, जिस स्थिति में आपको वर्चुअल डिस्ट्रक्टर्स की आवश्यकता होगी, और यह किसी भी अधिक खाली वर्ग नहीं होगा। :)


मैंने उस मामले के बारे में भी सोचा था, लेकिन आप ऐसी वस्तुओं की सूची के साथ क्या कर सकते हैं जो कोई व्यवहार नहीं उजागर करते हैं? सबसे अधिक संभावना है, आप किसी तरह से वास्तविक प्रकार का पता लगाएंगे और उपलब्ध तरीकों और क्षेत्रों तक पहुंचने के लिए कलाकारों का उपयोग करेंगे - निश्चित रूप से एक कोड गंध।
user281377

हाँ यह अच्छी बात है।
दस

1

एक स्थिति जहाँ आप इसे देख सकते हैं, जहाँ आप एक समान रूप से विषम प्रकार के संग्रह को संग्रहित करना चाहते हैं। मैं इसे एक महान विचार नहीं कह रहा हूं, यह एक कमजोर अमूर्तता या खराब डिजाइन का संकेत दे सकता है, लेकिन ऐसा होता है। जैसा कि आप उल्लेख करते हैं कि यह सामान को वर्गीकृत करने का एक तरीका है और यह उपयोगी और पूरी तरह से मान्य हो सकता है।

उदाहरण के लिए, आप बिल्लियों और कुत्तों को रखने के लिए एक संग्रह चाहते हैं। अपने डिजाइन में आप तय करते हैं कि उनके पास बहुत कुछ है इसलिए मैमल का एक आधार वर्ग है और अपने संग्रह में इस प्रकार का उपयोग करें (जैसे सूची)। सब अच्छा। फिर आप तय करते हैं कि आप अपने संग्रह में कुछ मेंढक जोड़ना चाहते हैं, लेकिन वे स्तनधारी नहीं हैं, इसलिए ऐसा करने का एक तरीका यह होगा कि आप मेंढक और मैमल्स को पशु का उपवर्ग बना दें, लेकिन शायद आप मेंढक और मैमल्स के बारे में ज्यादा नहीं सोच सकते। आम तो पशु खाली रहता है। फिर आप ममल के बजाय एनिमल के साथ अपना कलेक्शन टाइप करें और सब ठीक हो जाए।

वास्तविक जीवन में मुझे लगता है कि भले ही मैं एक खाली बेस क्लास जल्द ही बनाऊं या बाद में कुछ कार्यक्षमता वहां समाप्त हो जाए, लेकिन निश्चित रूप से वे मौजूद हैं।


एक सवाल, हालांकि, यह पूछना है: यदि प्रकारों में कुछ भी सामान्य नहीं है, तो उन्हें एक ही संग्रह में क्यों रखा जा रहा है? आपके द्वारा संग्रह में सभी वस्तुओं पर कोई ऑपरेशन नहीं किया जा सकता है, जो इस तरह के संग्रह को रखने के उद्देश्य को पराजित करता है। अब कुछ कृत्रिम ऑपरेशन हो सकते हैं जिन्हें आप तर्क को सरल बनाने के लिए दोनों में जोड़ना चाहते हैं - जैसे विज़िटर डिज़ाइन पैटर्न को लागू करना - जिस बिंदु पर यह फिर से उपयोगी हो सकता है, लेकिन अब उनके पास कुछ आम है ...
जूल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.