मैं एक ऐसी प्रणाली का निर्माण कैसे कर सकता हूं जिसमें निम्नलिखित हैं :
- अपरिवर्तनीय वस्तुओं के साथ शुद्ध कार्यों का उपयोग करना।
- केवल एक फ़ंक्शन डेटा में पास करें जिसे फ़ंक्शन की आवश्यकता है, कोई और अधिक (यानी कोई बड़ी एप्लिकेशन स्टेट ऑब्जेक्ट)
- फ़ंक्शंस के लिए बहुत अधिक तर्क देने से बचें।
- केवल कार्यों के लिए मापदंडों को पैक करने और अनपैक करने के लिए नई वस्तुओं के निर्माण से बचें, केवल कार्यों के लिए बहुत सारे मापदंडों से बचने के लिए। अगर मैं एक ही ऑब्जेक्ट के रूप में एक फ़ंक्शन में कई आइटम पैक करने जा रहा हूं, तो मैं चाहता हूं कि ऑब्जेक्ट उस डेटा का स्वामी हो, न कि कुछ बड़े पैमाने पर निर्मित
मुझे ऐसा प्रतीत होता है कि राज्य का मठ नियम # 2 को तोड़ता है, हालांकि यह स्पष्ट नहीं है क्योंकि यह मठ के माध्यम से बुना हुआ है।
मुझे लगता है कि मुझे किसी भी तरह से लेंस का उपयोग करने की आवश्यकता है, लेकिन गैर-कार्यात्मक भाषाओं के लिए इसके बारे में बहुत कम लिखा गया है।
पृष्ठभूमि
एक अभ्यास के रूप में, मैं अपने मौजूदा एप्लिकेशन को ऑब्जेक्ट-ओरिएंटेड शैली से कार्यात्मक शैली में परिवर्तित कर रहा हूं। पहली चीज जो मैं करने की कोशिश कर रहा हूं वह है कि जितना संभव हो सके आवेदन के इनर-कोर को अधिक से अधिक बनाना।
एक बात मैंने सुनी है कि विशुद्ध रूप से कार्यात्मक भाषा में "राज्य" का प्रबंधन कैसे किया जाता है, और यह मेरा मानना है कि राज्य के मठों द्वारा किया जाता है, क्या तार्किक रूप से, आप एक शुद्ध कार्य कहते हैं, "राज्य में गुजर रहा है" जैसा कि यह है, "तब, जब फ़ंक्शन वापस लौटता है, तो यह आपके लिए दुनिया की स्थिति के रूप में बदल जाता है।
वर्णन करने के लिए, जिस तरह से आप "हेल्लो वर्ल्ड" कर सकते हैं एक विशुद्ध रूप से कार्यात्मक तरीके से थोड़े है जैसे, आप अपने प्रोग्राम में स्क्रीन की उस स्थिति से गुजरते हैं, और उस पर मुद्रित "हैलो वर्ल्ड" के साथ स्क्रीन की स्थिति को वापस प्राप्त करते हैं। इसलिए तकनीकी रूप से, आप एक शुद्ध कार्य के लिए कॉल कर रहे हैं, और इसके कोई दुष्प्रभाव नहीं हैं।
उसके आधार पर, मैं अपने आवेदन के माध्यम से चला गया, और: 1. सबसे पहले अपने सभी एप्लिकेशन स्टेट को एक ही वैश्विक ऑब्जेक्ट (GameState) में डाल दिया 2. दूसरा, मैंने GameState को अपरिवर्तनीय बना दिया। आप इसे बदल नहीं सकते। यदि आपको एक बदलाव की आवश्यकता है, तो आपको एक नया निर्माण करना होगा। मैंने एक कॉपी-कंस्ट्रक्टर को जोड़कर ऐसा किया, जो वैकल्पिक रूप से एक या अधिक फ़ील्ड लेता है जो बदल गया। 3. प्रत्येक आवेदन के लिए, मैं एक पैरामीटर के रूप में GameState में पास करता हूं। फ़ंक्शन के भीतर, यह क्या करने जा रहा है, इसे करने के बाद, यह एक नया GameState बनाता है और इसे वापस करता है।
मेरे पास एक शुद्ध कार्यात्मक कोर है, और बाहर की तरफ एक लूप है जो कि गेमस्टैट को एप्लिकेशन के मुख्य वर्कफ़्लो लूप में फीड करता है।
मेरा प्रश्न:
अब, मेरी समस्या यह है कि, GameState में लगभग 15 विभिन्न अपरिवर्तनीय वस्तुएँ हैं। सबसे निचले स्तर पर कई कार्य केवल उन वस्तुओं में से कुछ पर काम करते हैं, जैसे स्कोर रखना। तो, मान लें कि मेरे पास एक फ़ंक्शन है जो स्कोर की गणना करता है। आज, GameState को इस फ़ंक्शन के लिए दिया गया है, जो नए GameState को एक नए स्कोर के साथ स्कोर को संशोधित करता है।
इसके बारे में कुछ गलत लगता है। फ़ंक्शन को GameState की संपूर्णता की आवश्यकता नहीं है। इसके लिए सिर्फ स्कोर ऑब्जेक्ट की जरूरत है। इसलिए मैंने इसे स्कोर में पास करने के लिए अपडेट किया, और स्कोर को वापस कर दिया।
यह समझ में आता है, इसलिए मैं अन्य कार्यों के साथ आगे बढ़ गया। कुछ कार्यों के लिए मुझे GameState से 2, 3 या 4 मापदंडों को पारित करने की आवश्यकता होगी, लेकिन जैसा कि मैंने आवेदन के बाहरी कोर के सभी तरह से पैटर्न का उपयोग किया है, मैं अधिक से अधिक आवेदन स्थिति से गुजर रहा हूं। जैसे, वर्कफ़्लो लूप के शीर्ष पर, मैं एक विधि कहूंगा, वह विधि कहेगा जो एक विधि कहेगा, आदि, नीचे सभी तरह से जहां स्कोर की गणना की जाती है। इसका मतलब है कि वर्तमान स्कोर को उन सभी परतों के माध्यम से पारित किया जाता है, क्योंकि बहुत नीचे स्थित एक फ़ंक्शन स्कोर की गणना करने जा रहा है।
इसलिए अब मेरे पास कई दर्जन मापदंडों के साथ कार्य हैं। मैं मापदंडों की संख्या को कम करने के लिए उन मापदंडों को एक वस्तु में डाल सकता हूं, लेकिन फिर मैं उस वर्ग को राज्य के आवेदन के राज्य का मास्टर स्थान होना चाहूंगा, बजाय एक वस्तु के जो बस कॉल के समय बस निर्माण से बचने के लिए कई मापदंडों में, और फिर उन्हें अनपैक करें।
इसलिए अब मैं सोच रहा हूं कि मुझे जो समस्या है, वह यह है कि मेरे कार्य बहुत गहराई से निहित हैं। यह छोटे कार्य करने की इच्छा का परिणाम है, इसलिए जब कोई फ़ंक्शन बड़ा हो जाता है, तो मैं इसे रिफ्लेक्टर करता हूं, और इसे कई छोटे कार्यों में विभाजित करता हूं। लेकिन ऐसा करने से एक गहरी पदानुक्रम का उत्पादन होता है, और आंतरिक कार्यों में पारित कुछ भी बाहरी फ़ंक्शन को पारित करने की आवश्यकता होती है, भले ही बाहरी फ़ंक्शन सीधे उन वस्तुओं पर काम नहीं कर रहा हो।
ऐसा लग रहा था कि जिस तरह से इस समस्या से बचा जा रहा है उसी तरह से GameState में गुजर रहा है। लेकिन मैं फ़ंक्शन की आवश्यकता से अधिक जानकारी को किसी फ़ंक्शन में पास करने की मूल समस्या पर वापस आ गया हूं।