क्या यह कोड की बदबू आना ठीक है अगर यह किसी अन्य समस्या का आसान समाधान है? [बन्द है]


31

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

तो ठीक यही हमने किया; हमने एक बहुत ही सुंदर वास्तुकला बनाई, जिसने हमें विभिन्न घटकों में बुलेट के व्यवहार को बंद करने की अनुमति दी, जो कि बुलेट इंस्टेंस से जुड़ी हो सकती है, जो कि यूनिटी के घटक प्रणाली की तरह है। यह अच्छी तरह से काम करता था, यह आसानी से एक्स्टेंसिबल था, यह लचीला था और हमारे सभी ठिकानों को कवर करता था, लेकिन थोड़ी समस्या थी।

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

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

क्या यह ठीक है कि हमारी एक कक्षा एक देव वस्तु में बदल गई, बस एक और समस्या के साथ काम करना आसान हो गया? सामान्य तौर पर, यदि आपके कोड में एक अलग समस्या का आसान समाधान है, तो कोड गंध होना ठीक है?


1
खैर ... यह जवाब देने के लिए थोड़े कठिन है। मेरी राय में सं। खासकर अगर आप दूसरे लोगों के साथ मिलकर काम करते हैं। यदि आप अकेले काम करते हैं तो आप जो चाहें कर सकते हैं। लेकिन सामान्य तौर पर यह इस बात पर निर्भर करता है कि आप किसके साथ काम करते हैं।
सार्कास्टिक आलू

13
"अगर यह बेवकूफ है, और यह काम करता है, तो यह बेवकूफ नहीं है।" यह कहा जा रहा है, आपको यह विचार करना होगा कि भले ही यह ठीक उसी तरह से काम करे जैसा आप चाहते हैं, चाहे आप उस देव वर्ग पर भविष्य कोडिंग नहीं कर रहे हों, असंभव के कारण कि आपने इसे कैसे ठीक किया।
फ्लटर

8
यह बेहतर है कि आप बदबू मारें और जान लें कि आपको बदबू आ रही है, केवल दूसरे लोगों को नोटिस करें। :)
रिएक्टगुलर

1
लगता है कि आपको एक एडेप्टर वर्ग की आवश्यकता है जो आपके प्रक्रियात्मक कोड को एक गैर-ओओ इंटरफ़ेस प्रदान करता है, ताकि आप अपने बाकी कोड को साफ (एर) रख सकें।
nikie

1
ऐसा लगता है कि आप एक अद्भुत प्रणाली का निर्माण करते हैं और यह सब नरक में उड़ाने का फैसला किया है अब यह एक सुविधा पर अपेक्षित रूप से काम नहीं करता है। क्या आप वास्तव में यही चाहते हैं? अपने काम पर गर्व करो!
मस्त

जवाबों:


74

वास्तविक दुनिया के कार्यक्रमों का निर्माण करते समय, अक्सर एक तरफ व्यावहारिक रहने और दूसरे पर 100% स्वच्छ रहने के बीच एक व्यापार-बंद होता है। यदि स्वच्छ रहना आपको समय में अपने उत्पाद को जहाज करने से रोकता है, तो आप दरवाजे से बाहर निकलने वाली d *** d को पाने के लिए थोड़ा सा डक्ट-टेप के साथ बेहतर हैं ।

ने कहा कि, अपने विवरण अलग लगता है - यह आप को जोड़ने के लिए नहीं जा रहे हैं लगता है एक छोटे से डक्ट टेप का सा है, यह लगता है कि आप अपने पूरे वास्तुकला बर्बाद करने के लिए है क्योंकि आप लंबी और कठिन पर्याप्त एक बेहतर समाधान के लिए देखो नहीं किया जा रहे हैं। इसलिए पीएसई पर यहां किसी के लिए मांग करने के बजाय जो आपको इस पर आशीर्वाद देता है, आप बेहतर तरीके से एक अलग सवाल पूछ सकते हैं जहां आप कुछ समस्याओं का वर्णन करते हैं जो आपके पास गहराई में हैं, और देखो कि क्या कोई आपको एक विचार प्रदान करता है जो भगवान से बचता है -क्लास दृष्टिकोण।

हो सकता है कि बुलेट क्लास को अन्य वर्गों के झुंड के रूप में बनाया जा सकता है, इसलिए बुलेट क्लास छोटा हो जाता है। हो सकता है कि रणनीति पैटर्न मदद कर सकता है ताकि गोली विभिन्न व्यवहार वस्तुओं को अलग-अलग रणनीति वस्तुओं को सौंप सके। हो सकता है कि आपको अपने बुलेट घटक और आपके प्रक्रियात्मक जनरेटर के बीच बस एक एडाप्टर की आवश्यकता हो। लेकिन ईमानदारी से, आपके सिस्टम के अधिक विवरण को जाने बिना, कोई केवल अनुमान लगा सकता है।


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

2
कोड को छोटे टुकड़ों में विभाजित करने के लिए फेसडे / रणनीति पर अच्छे सुझाव। हालांकि अधिक जानकारी के बिना यह जानना मुश्किल है कि क्या सुझाव दिया जाए।
user949300

25

दिलचस्प सवाल। मैं अपने पिछले अनुभवों के कारण थोड़ा पक्षपाती हूं, जो मुझे उत्तर देने के लिए प्रेरित करता है।

संक्षिप्त उत्तर: हमने कभी सीखना नहीं छोड़ा। जब आप उस तरह की दीवार से टकराते हैं, तो यह आपके वास्तु / डिज़ाइन कौशल को सुधारने का एक मौका होता है, न कि कोड स्मेल जोड़ने का बहाना।

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

मुझे 5 व्हाट्स विशेष रूप से मददगार मिले। यहाँ आपका स्पष्टीकरण पहले की तरह ही पढ़ता है क्यों:

  • "अब हमारे पास यह देव वर्ग है" क्यों?
  • "क्योंकि यह प्रक्रियात्मक पीढ़ी के एल्गोरिथ्म को सरल करता है"

यह वास्तव में क्या सरलीकृत है? और ऐसा क्यों है? उस लाइन के साथ चलते रहें और आमतौर पर ऐसा होता है कि आप अधिक मूलभूत समस्याओं को पहचानना शुरू कर देते हैं, लेकिन साथ ही, वे आपको और अधिक मौलिक समाधानों की भी अनुमति देते हैं।

लंबी कहानी छोटी, हाथ में समस्या और विशेष रूप से इसके कारणों के बारे में अधिक गहराई से सोचने के बाद, मेरे अनुभव में मूल प्रश्न सभी प्रतिभागियों के लिए शून्य और पूरी तरह से निर्बाध हो रहा है। यदि आपको संदेह है, तो उन्हें चुनौती दें और या तो वे चले जाएंगे, या आपको पता चल जाएगा कि आपको क्या करना है। माइंड यू, मेरी राय में कोड / डिज़ाइन के बारे में ये संदेह होना एक अच्छा संकेत है। दूसरे लोग इसे आंत की भावना कहते हैं, लेकिन इन समस्याओं को चुनौती देने के लिए, आपको पहले उन्हें पहचानना होगा। जब से आपने वह पहला कदम बनाया, बधाई! अब खरगोश छेद नीचे जाओ ...


9

इस तरह के एक देव वर्ग का होना कभी भी वांछनीय नहीं है, क्योंकि इसका मतलब यह नहीं है कि आपकी गोलियां अब अखंड वस्तुएं हैं, लेकिन आपके प्रक्रियात्मक पीढ़ी के एल्गोरिथ्म के लिए भी यही होता है।

पहला कदम यह विश्लेषण करना होगा कि वास्तव में आपके एआई को आपके पैटर्न की जटिलता से निपटने में इतनी परेशानी क्यों हुई?

क्या आपने संयोगवश, अपने एआई को एक देव वर्ग की वस्तु में बदलने की कोशिश की, जो कि हर एक संभावित संपत्ति के शब्दार्थ के बारे में पूरी तरह से जानते हैं? यदि आपने किया, तो यह समस्या कहां से उत्पन्न हुई।

तब समाधान सभी रणनीतियों को बुलेट क्लास में एकीकृत करने के लिए नहीं होता था, बल्कि एआई कोर से एआई के लिए खुद को रणनीति के कार्यान्वयन के लिए संकेत को लोड करने से रोकता था।

इसने आपको मूल रूप से वांछित लचीलापन दिया होगा, जिसमें नई रणनीतियों द्वारा प्रणाली का विस्तार करने का विकल्प शामिल है, जैसा कि आप विरासत व्यवहार के साथ साइड इफेक्ट में चलने के डर के बिना चाहते हैं।

इसके बजाय अब आपके पास देव वस्तुओं से जुड़ी सभी समस्याएं हैं: केवल आपका देव वर्ग ही समझने के लिए कठिन नहीं है, अखंड देव को कठोर करना है, लेकिन एक ही ऐसे देव वर्ग तक पहुंचने वाले अन्य सभी घटकों के लिए भी जाता है। अमूर्तता की कमी के कारण, आपका एआई अब इसी तरह की जटिलता के उन्मूलन में बदल जाता है क्योंकि उसे अब सभी अनावश्यक, व्यक्तिगत गुणों के बारे में पता होना चाहिए।

यहां तक ​​कि अभी, आप पहले से ही रखरखाव के साथ समस्याओं का सामना कर रहे हैं। ये समस्याएँ बदतर होती जा रही हैं, खासकर जैसे ही आप टीम के सदस्यों को ढीला करते हैं जो अभी भी एक संज्ञानात्मक मॉडल है कि उस वर्ग को कैसे काम करना चाहिए।

अब तक हर एक परियोजना का मुझे सामना करना पड़ा जिसने ऐसे देव वर्गों या देव कार्यों का उपयोग किया या तो पूरी तरह से खरोंच से हटा दिया गया था या कोई अपवाद नहीं था।


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

इस तरह के एक इंटरफेस को देखते हुए, कोड को अलग-अलग संयोजनों को संभालने के बिना, किसी भी क्षमता के संयोजन के साथ वस्तुओं को अलग करना संभव है। इंटरफेस को अलग करना कई अलग-अलग प्रॉक्सी वर्गों को लिखने के लिए आवश्यक होगा, क्योंकि एक प्रकार के लिए प्रॉक्सी, जो विधि X का समर्थन करता है, का उपयोग उन वस्तुओं को लपेटने के लिए नहीं किया जा सकता है जो X नहीं कर सकते हैं, और प्रॉक्सी जो ऐसी वस्तुओं को लपेट सकते हैं जो X नहीं कर सकते। ' टी एक्स को एक्सपोज करने में सक्षम हो सकता है, भले ही वह एक ऐसी वस्तु को लपेट रहा हो, जो उसका समर्थन कर सके।
सुपरकाट

8

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

अपने कार्यालय के आसपास पूछें कि क्या लोगों के पास इसे ठीक करने के लिए कोई विचार है। अधिकांश स्थानों पर मैंने काम किया है, लगभग 10-20% प्रोग्रामर के पास इस तरह की चीज़ के लिए एक वास्तविक आदत है, और बस मौके का इंतजार कर रहे हैं। पता लगाओ कि वे लोग कौन हैं। अक्सर, यह आपका नया काम है जो वर्तमान वास्तुकला में ऐतिहासिक रूप से निवेश नहीं किया गया है जो सबसे आसानी से विकल्प देख सकते हैं। अपने एक दिग्गज के साथ उनकी जोड़ी बनाएं और आप आश्चर्यचकित हो सकते हैं कि वे एक साथ क्या लेकर आते हैं।


2

कुछ मामलों में यह निश्चित रूप से स्वीकार्य है। हालाँकि, मुझे यह विश्वास करना मुश्किल है कि प्रक्रियात्मक पीढ़ी और आपके अच्छे संलग्न / घटक आधारित व्यवहार वास्तुकला दोनों का उपयोग करके कोई अच्छा समाधान नहीं है। यदि सभी व्यवहार जहां सिर्फ बुलेट क्लास में खींचे गए हैं, तो देव वस्तु और साफ-सुथरे आर्किटेक्चर संस्करण के बीच कोई कार्यात्मक अंतर नहीं है। आपके प्रक्रियात्मक पीढ़ी के एल्गोरिदम का उपयोग करने के लिए यह कितना कठिन था?

मुझे लगता है कि एक नया सवाल (शायद यहाँ, या gamedev.stackexchange.com पर?), जहाँ आप यह समझते हैं कि आपको अपनी वास्तुकला में क्या समस्याएँ हैं। वास्तव में दिलचस्प होगा। अगर आप कोई नया सवाल करते हैं तो हमें भी बताएं!


3
क्या आप ऐसी स्थिति के लिए कोई उदाहरण प्रदान कर सकते हैं जहां एक देव वर्ग स्वीकार्य और वांछनीय होगा, जबकि यह वर्ग व्यक्तिगत स्रोतों का सिर्फ एक स्वचालित संकलन नहीं है?
Ext3h

स्वीकार्य होने के साथ मैं "अगर किसी अन्य समस्या का आसान समाधान स्वीकार करता है तो क्या कोड बदबू आना ठीक है?" भगवान की कक्षाएं आमतौर पर रचना का उपयोग करके आसानी से हल करने योग्य होती हैं। लेकिन हाँ कुछ कोड गंध हैं जो निश्चित रूप से 100% से छुटकारा पाने के लायक नहीं हैं। अंत में काम करने के लिए कुछ व्यावहारिकता की आवश्यकता होती है :)। (इसका मतलब यह नहीं है कि मुझे लगता है कि आपको एक अभ्यास पर सबसे अच्छा अभ्यास करना चाहिए। मेरा मानना ​​है कि अधिकांश सॉफ्टवेयर हाउस बेहतर अभ्यासों का अधिक सख्ती से पालन करने से बेहतर होंगे)।
रॉय टी।

0

प्रेरणा के लिए, आप कार्यात्मक प्रोग्रामिंग, या अधिक सटीक, तंग-अनुरूप प्रकारों पर एक नज़र रखना चाहते हैं। यह विचार किया जा रहा है कि आपके द्वारा उपलब्ध प्रकार प्रणाली में चीजों का प्रतिनिधित्व करना असंभव नहीं है। उदाहरण के लिए, मान लें कि आपके पास एक बंदूक है जिसमें "बुलेट्स" और "होल्ड बुलेट्स" घटक हैं। यदि वे दो अलग-अलग घटक हैं, तो ऐसे कॉन्फ़िगरेशन हैं जो समझ में नहीं आते हैं - आपके पास एक बंदूक हो सकती है जो गोलियों को मारती है लेकिन उसके भंडारण में कोई भी नहीं है, या एक बंदूक जो गोलियों को संग्रहीत करती है लेकिन उन्हें आग नहीं लगाती है।

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

जबकि आपके उदाहरण बहुत अधिक जटिल हो सकते हैं, कुंजी अभी भी संभावित संयोजनों को सीमित कर रही है, बाधाओं को जोड़ रही है। एक तरह से, अगर यह प्रक्रियात्मक पीढ़ी के लिए सही होने के लिए बहुत जटिल है, तो यह शायद वैसे भी बहुत जटिल है। हथियारों को डिजाइन करते समय अपने आप को विवश करने के सभी तरीकों के बारे में सोचें - क्या आप अपने आप को "सही बताते हैं, इस बंदूक में पहले से ही एक फ्लेमेथ्रो है, ग्रेनेड लांचर को जोड़ने का कोई मतलब नहीं है"? यह कुछ ऐसा है जिसे आप अपने उत्तराधिकार में शामिल कर सकते हैं। आप एक संभावना तंत्र का उपयोग करना चाह सकते हैं जो कि प्रत्येक घटक होने के निश्चित अवसर देने की तुलना में थोड़ा अधिक जटिल है - आपके पास ऐसे घटक हो सकते हैं जो एक दूसरे को बाहर करने की प्रवृत्ति रखते हैं, या ऐसे घटक जो एक साथ अच्छी तरह से काम करते हैं।

और अंतिम, विचार करें कि क्या यह वास्तव में एक बड़ी समस्या है। क्या यह खेल का मज़ा बर्बाद कर रहा है? क्या परिणाम बंदूकें जो बेकार हैं या प्रबल हैं? कितना? क्या 10 में से एक निरर्थक है? बॉर्डरलैंड्स (प्रक्रियात्मक रूप से उत्पन्न हथियार प्रभावों के साथ) जैसे खेल अक्सर निरर्थक प्रभाव संयोजनों की अनदेखी करते हैं - 16x गुंजाइश के साथ शॉटगन होने की क्या बात है? और फिर भी बॉर्डरलैंड में बहुत बार ऐसा होता है। यह सिर्फ हंसी के लिए खेला जाता है, बजाय इसके कि इसे पीढ़ी तंत्र की विफलता माना जाता है :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.