BobDalgleish ने पहले ही नोट किया है कि इस (विरोधी) पैटर्न को " ट्रम्प डेटा " कहा जाता है ।
मेरे अनुभव में, अत्यधिक ट्रम्प डेटा का सबसे आम कारण लिंक किए गए राज्य चर का एक गुच्छा है जो वास्तव में किसी ऑब्जेक्ट या डेटा संरचना में संक्षिप्त होना चाहिए। कभी-कभी, डेटा को ठीक से व्यवस्थित करने के लिए वस्तुओं का एक गुच्छा घोंसला करना भी आवश्यक हो सकता है।
एक साधारण उदाहरण के लिए, एक खेल एक अनुकूलन खिलाड़ी चरित्र है, जैसे गुणों के साथ विचार करें playerName
, playerEyeColor
इतने पर और। बेशक, खिलाड़ी के खेल के नक्शे पर एक भौतिक स्थिति होती है, और विभिन्न अन्य गुण जैसे, कहते हैं, वर्तमान और अधिकतम स्वास्थ्य स्तर, और इसी तरह।
इस तरह के खेल के पहले पुनरावृत्ति में, इन सभी गुणों को वैश्विक चर में बनाने के लिए एक पूरी तरह से उचित विकल्प हो सकता है - आखिरकार, केवल एक ही खिलाड़ी है, और खेल में लगभग हर चीज किसी न किसी तरह से खिलाड़ी को शामिल करती है। इसलिए आपके वैश्विक राज्य में चर हो सकते हैं जैसे:
playerName = "Bob"
playerEyeColor = GREEN
playerXPosition = -8
playerYPosition = 136
playerHealth = 100
playerMaxHealth = 100
लेकिन कुछ बिंदु पर, आप पा सकते हैं कि आपको इस डिज़ाइन को बदलने की आवश्यकता है, शायद इसलिए कि आप खेल में एक मल्टीप्लेयर मोड जोड़ना चाहते हैं। पहले प्रयास के रूप में, आप उन सभी चर को स्थानीय बनाने की कोशिश कर सकते हैं, और उन्हें उन कार्यों को पारित कर सकते हैं जिनकी उन्हें आवश्यकता है। हालाँकि, आप तब पा सकते हैं कि आपके खेल में एक विशेष क्रिया में एक फ़ंक्शन कॉल श्रृंखला शामिल हो सकती है, जैसे:
mainGameLoop()
-> processInputEvent()
-> doPlayerAction()
-> movePlayer()
-> checkCollision()
-> interactWithNPC()
-> interactWithShopkeeper()
... और interactWithShopkeeper()
फ़ंक्शन में दुकानदार को नाम से खिलाड़ी को संबोधित किया जाता है, इसलिए अब आपको अचानक उन सभी कार्यों के playerName
माध्यम से ट्रैम्प डेटा के रूप में पास करना होगा । और, ज़ाहिर है, अगर दुकानदार सोचता है कि नीली आंखों वाले खिलाड़ी भोले हैं, और उनके लिए उच्च कीमतें चार्ज करेंगे, तो आपको कार्यों की पूरी श्रृंखला से गुजरना होगा , और इसी तरह।playerEyeColor
उचित समाधान है, इस मामले में, पाठ्यक्रम एक खिलाड़ी उद्देश्य यह है कि नाम समाहित परिभाषित करने के लिए, आंखों का रंग, स्थिति, स्वास्थ्य और खिलाड़ी चरित्र के किसी भी अन्य संपत्तियों की है। इस तरह, आपको केवल उन सभी कार्यों के लिए उस एकल ऑब्जेक्ट को पास करना होगा जो किसी भी तरह खिलाड़ी को शामिल करता है।
इसके अलावा, ऊपर दिए गए कई कार्य स्वाभाविक रूप से उस खिलाड़ी ऑब्जेक्ट के तरीकों में किए जा सकते हैं, जो स्वचालित रूप से उन्हें खिलाड़ी के गुणों तक पहुंच प्रदान करेगा। एक तरह से, यह सिंटैक्टिक शुगर है, क्योंकि किसी ऑब्जेक्ट को विधि पर कॉल करने से प्रभावी तरीके से किसी भी तरह से ऑब्जेक्ट को एक छिपे हुए पैरामीटर के रूप में पास किया जाता है, लेकिन यह ठीक से उपयोग किए जाने पर कोड को स्पष्ट और अधिक प्राकृतिक बनाता है।
बेशक, एक विशिष्ट खेल में खिलाड़ी की तुलना में बहुत अधिक "वैश्विक" राज्य होगा; उदाहरण के लिए, आपके पास निश्चित रूप से किसी प्रकार का एक मानचित्र होगा, जिस पर खेल होता है, और नक्शे पर चलते हुए गैर-खिलाड़ी पात्रों की एक सूची और शायद उस पर रखी गई वस्तुएं, और इसी तरह। आप उन सभी को ट्रम्प ऑब्जेक्ट के रूप में भी पास कर सकते हैं, लेकिन यह फिर से आपके विधि तर्कों को अव्यवस्थित कर देगा।
इसके बजाय, समाधान के लिए वस्तुओं को किसी भी अन्य वस्तुओं के संदर्भ में स्टोर करना है, जिनके साथ उनके स्थायी या अस्थायी संबंध हैं। इसलिए, उदाहरण के लिए, खिलाड़ी ऑब्जेक्ट (और शायद किसी भी एनपीसी ऑब्जेक्ट्स) को संभवतः "गेम वर्ल्ड" ऑब्जेक्ट के लिए एक संदर्भ स्टोर करना चाहिए, जिसमें वर्तमान स्तर / मैप का संदर्भ होगा, ताकि इस तरह की विधि की player.moveTo(x, y)
आवश्यकता न हो स्पष्ट रूप से मानचित्र को एक पैरामीटर के रूप में दिया जाए।
इसी तरह, अगर हमारे खिलाड़ी चरित्र में, एक पालतू कुत्ता है, जो उनके आसपास था, तो हम स्वाभाविक रूप से कुत्ते को एक वस्तु में वर्णन करने वाले सभी राज्य चरों को समूहीकृत करेंगे, और खिलाड़ी को कुत्ते को एक संदर्भ देंगे (ताकि खिलाड़ी कर सकें , कहते हैं, नाम से कुत्ते को बुलाओ) और इसके विपरीत (ताकि कुत्ता जानता है कि खिलाड़ी कहां है)। और, ज़ाहिर है, हम शायद खिलाड़ी और कुत्ते की वस्तुओं को एक अधिक सामान्य "अभिनेता" वस्तु के दोनों उपवर्ग बनाना चाहते हैं, ताकि हम नक्शे के चारों ओर घूमते हुए एक ही कोड का पुन: उपयोग कर सकें।
Ps। भले ही मैंने एक खेल को उदाहरण के रूप में इस्तेमाल किया है, लेकिन अन्य प्रकार के कार्यक्रम हैं जहां ऐसे मुद्दे सामने आते हैं। मेरे अनुभव में, हालांकि, अंतर्निहित समस्या हमेशा एक जैसी रहती है: आपके पास अलग-अलग चर (चाहे स्थानीय या वैश्विक) का एक गुच्छा हो जो वास्तव में एक या एक से अधिक इंटरलिंक किए गए ऑब्जेक्ट में एक साथ बांटा जाना चाहते हैं। आपके कार्यों में घुसपैठ करने वाले "ट्रम्प डेटा" में "ग्लोबल" विकल्प सेटिंग्स या कैश्ड डेटाबेस क्वेश्चंस या स्टेट वैक्टर हैं, जो संख्यात्मक सिमुलेशन में हैं, समाधान हमेशा उस प्राकृतिक संदर्भ की पहचान करने के लिए होता है, जो डेटा से संबंधित है, और इसे किसी ऑब्जेक्ट में बनाते हैं। (या जो भी आपकी चुनी हुई भाषा में निकटतम समकक्ष है)।