"सब कुछ एक नक्शा है", क्या मैं यह सही कर रहा हूँ?


69

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

  • क्लोजर मुहावरेदार कार्यात्मक प्रोग्रामिंग है
  • अधिकांश राज्य अपरिवर्तनीय है

मैंने स्लाइड से विचार लिया "सब कुछ एक नक्शा है" (11 मिनट, 6 सेकंड से> 29 मिनट तक)। कुछ बातें वे कहते हैं:

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

    ;; Bad
    (defn complex-process []
      (let [a (get-component @global-state)
            b (subprocess-one a) 
            c (subprocess-two a b)
            d (subprocess-three a b c)]
        (reset! global-state d)))
    
    ;; Good
    (defn complex-process [state]
      (-> state
        subprocess-one
        subprocess-two
        subprocess-three))
    

    मैं समझता हूं कि अधिकांश प्रोग्रामर क्लोजर से परिचित नहीं हैं, इसलिए मैं इसे अनिवार्य शैली में फिर से लिखूंगा:

    ;; Good
    def complex-process(State state)
      state = subprocess-one(state)
      state = subprocess-two(state)
      state = subprocess-three(state)
      return state
    

    ये हैं फायदे:

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

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

update(gameState)
  ...
  gameState = handleUnitCollision(gameState)
  ...
  gameState = handleLoot(gameState)
  ...

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

मुझे चिंता है कि एक दिन मैं उठूंगा और महसूस करूंगा कि यह पूरी डिजाइन एक दिखावा है और मैं वास्तव में सिर्फ बिग बॉल ऑफ मड विरोधी पैटर्न को लागू कर रहा हूं ।


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

अपडेट करें

मैं इस पैटर्न के साथ 6+ महीने का कोडिंग कर रहा हूं। आमतौर पर इस समय तक मैं भूल जाता हूं कि मैंने क्या किया है और वह यह है कि "क्या मैंने इसे साफ तरीके से लिखा है?" खेलने के लिए आता है। अगर मैंने नहीं किया, तो मैं वास्तव में संघर्ष करूँगा। अब तक, मैं बिल्कुल संघर्ष नहीं कर रहा हूं।

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

मैं सीधे उन लोगों को जवाब देना चाहता हूं जिनके पास कोडिंग के इस तरीके के साथ पहले से ही एक बुरा व्यक्तिगत अनुभव है। मुझे तब यह पता नहीं था, लेकिन मुझे लगता है कि हम वास्तव में कोड लिखने के दो अलग-अलग तरीकों के बारे में बात कर रहे हैं। जिस तरह से मैंने किया है वह अन्य लोगों की तुलना में अधिक संरचित प्रतीत होता है। जब किसी को "सब कुछ एक नक्शा है" के साथ एक बुरा व्यक्तिगत अनुभव होता है, तो वे इस बारे में बात करते हैं कि इसे बनाए रखना कितना कठिन है:

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

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

संदर्भ कार्यान्वयन के लिए देखने के लिए एक स्थान है (यानी: स्कीमा)। यह संदर्भ कार्यान्वयन कोड का उपयोग करता है, इसलिए यह पुराना नहीं हो सकता।

दूसरे बिंदु के रूप में, मैं संदर्भ कार्यान्वयन के बाहर के नक्शे में कुंजियाँ नहीं जोड़ता / हटाता, मैं पहले से ही वहां क्या है, इसे म्यूट करता हूं। मेरे पास स्वचालित परीक्षणों का एक बड़ा सूट भी है।

यदि यह वास्तुकला अंततः अपने स्वयं के वजन के तहत ढह जाती है, तो मैं एक दूसरा अपडेट जोड़ूंगा। अन्यथा, मान लें कि सब कुछ ठीक चल रहा है :)


2
अच्छा सवाल (+1)! मुझे गैर-कार्यात्मक (या बहुत दृढ़ता से कार्यात्मक नहीं) भाषा में कार्यात्मक मुहावरों को आजमाने और लागू करने के लिए यह बहुत उपयोगी अभ्यास लगता है।
जियोर्जियो

15
जो कोई भी आपको यह बताने जा रहा है कि ओओ-शैली की जानकारी छिपाना (गुणों और सहायक कार्यों के साथ) एक बुरी बात है (आमतौर पर नगण्य) प्रदर्शन के कारण, और फिर आपको अपने सभी मापदंडों को एक नक्शे में बदलने के लिए कहता है, जो आपको देता है (बहुत अधिक) एक हैश लुकअप के ओवरहेड हर बार जब आप एक मान प्राप्त करने का प्रयास करते हैं, तो सुरक्षित रूप से अनदेखा किया जा सकता है।
मेसन व्हीलर

4
@MasonWheeler आपको इस बारे में सही बताने देता है। क्या आप हर दूसरे बिंदु को शून्य करने जा रहे हैं क्योंकि वह इस वजह से गलत है?
डैनियल कपलान

9
पायथन में (और मैं जावास्क्रिप्ट सहित अधिकांश गतिशील भाषाओं को मानता हूं), वस्तु वास्तव में किसी भी तरह से एक तानाशाह / मानचित्र के लिए सिंटैक्स चीनी है।
रेयान

6
@ इवानप्लिस: बिग-ओ नोटेशन भ्रामक हो सकता है। साधारण तथ्य यह है, दो या तीन अलग-अलग मशीन कोड निर्देशों के साथ सीधे पहुंच की तुलना में कुछ भी धीमा है, और कुछ ऐसा जो एक फ़ंक्शन कॉल के रूप में अक्सर होता है, वह ओवरहेड बहुत जल्दी जोड़ देगा।
मेसन व्हीलर

जवाबों:


42

मैंने एक एप्लिकेशन का समर्थन किया है, जहां 'सब कुछ पहले एक नक्शा है'। यह एक भयानक विचार है। कृपया यह मत करो!

जब आप फ़ंक्शन को दिए गए तर्कों को निर्दिष्ट करते हैं, तो यह जानना बहुत आसान हो जाता है कि फ़ंक्शन को किन मूल्यों की आवश्यकता है। यह फ़ंक्शन के लिए बाहरी डेटा पास करने से बचता है जो सिर्फ वें प्रोग्रामर को विचलित करता है - पारित हर मूल्य का तात्पर्य है कि यह आवश्यक है, और इससे प्रोग्रामर को आपके कोड का समर्थन करने का पता लगाना पड़ता है कि डेटा की आवश्यकता क्यों है।

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

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

संपादित करें - उदाहरण

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

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

अगले कार्य डेटाबेस से डेटा खींच लेंगे। या, बल्कि, वे डेटा एक्सेस लेयर में मैप को पास करेंगे। DAL यह जाँच करेगा कि मानचित्र में क्वेरी को निष्पादित करने के तरीके को नियंत्रित करने के लिए कुछ मान सम्‍मिलित हैं या नहीं। यदि 'जस्टकाउंट' एक कुंजी थी, तो क्वेरी 'बार से चुनिंदा फू' होगी। जिन कार्यों को पहले कहा गया था, उनमें से कोई एक हो सकता है जो मानचित्र में 'जस्टकाउंट' को जोड़ता है। क्वेरी परिणामों को उसी नक्शे में जोड़ा जाएगा।

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

कोड प्रभावी रूप से एक अखंड गड़बड़ी थी, जिसे आपको यह जानने के लिए पूरी तरह से समझना होगा कि मानचित्र में एक प्रविष्टि कहां से आई है।


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

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

28

व्यक्तिगत रूप से, मैं उस प्रतिमान को या तो प्रतिमान में नहीं सुझाऊंगा। बाद में इसके बारे में तर्क करने के लिए इसे और अधिक कठिन बनाने की कीमत पर शुरू में लिखना आसान बनाता है।

उदाहरण के लिए, प्रत्येक उपप्रकार फ़ंक्शन के बारे में निम्नलिखित प्रश्नों के उत्तर देने का प्रयास करें:

  • किन क्षेत्रों में stateइसकी आवश्यकता है?
  • यह किन क्षेत्रों को संशोधित करता है?
  • कौन से क्षेत्र अपरिवर्तित हैं?
  • क्या आप कार्यों के क्रम को सुरक्षित रूप से पुनर्व्यवस्थित कर सकते हैं?

इस पैटर्न के साथ, आप पूरे फ़ंक्शन को पढ़े बिना उन सवालों के जवाब नहीं दे सकते।

ऑब्जेक्ट ओरिएंटेड भाषा में, पैटर्न और भी कम समझ में आता है, क्योंकि ट्रैकिंग स्टेट यह है कि ऑब्जेक्ट क्या करते हैं।


2
"अपरिवर्तनीयता का लाभ आपके अपरिवर्तनीय वस्तुओं को प्राप्त करने के तरीके को कम करता है" क्यों? क्या यह प्रदर्शन या रखरखाव पर टिप्पणी है? कृपया उस वाक्य पर विस्तार से बताएं।
डैनियल कपलान

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

3
समझा। क्या यह "अपरिमेय भाषाओं में अपरिवर्तनीय डेटा" समस्या या "अपरिवर्तनीय डेटा" समस्या है? IE: शायद यह Clojure कोड में कोई समस्या नहीं है। लेकिन मैं देख सकता हूं कि जेएस में यह कैसा है। इसे करने के लिए सभी बॉयलरप्लेट कोड लिखना भी एक दर्द है।
डैनियल कपलान

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

3
@MattFenwick मैं व्यक्तिगत रूप से इमूटेबल की तरह है। थ्रेडिंग से निपटने के दौरान मैं अपरिवर्तनीय चीजों के बारे में जानता हूं और काम कर सकता हूं और उन्हें सुरक्षित रूप से कॉपी कर सकता हूं। मैंने इसे एक पैरामीटर कॉल में रखा और इसे बिना किसी चिंता के पास कर दिया कि कोई मेरे पास वापस आने पर इसे संशोधित कर देगा। यदि कोई एक जटिल गेम स्टेट के बारे में बात कर रहा है (प्रश्न ने इसे एक उदाहरण के रूप में इस्तेमाल किया है - मुझे नेटहॉक गेम स्टेट को एक अपरिवर्तनीय के रूप में 'सरल' के रूप में कुछ के बारे में सोचने से डर लगेगा), अपरिवर्तनीयता शायद गलत दृष्टिकोण है।

12

आप जो कर रहे हैं, वह प्रभावी रूप से एक मैनुअल स्टेट मोनड है; मैं क्या करूँगा (सरलीकृत) बाइंड कॉम्बिनेटर का निर्माण कर रहा हूं और उस का उपयोग करते हुए अपने तार्किक चरणों के बीच कनेक्शन को फिर से व्यक्त करता हूं:

function stateBind() {
    var computation = function (state) { return state; };
    for ( var i = 0 ; i < arguments.length ; i++ ) {
        var oldComp = computation;
        var newComp = arguments[i];
        computation = function (state) { return newComp(oldComp(state)); };
    }
    return computation;
}

...

stateBind(
  subprocessOne,
  subprocessTwo,
  subprocessThree,
);

आप stateBindउप-वर्ग से विभिन्न उपप्रकारों का निर्माण करने के लिए भी उपयोग कर सकते हैं , और उचित रूप से आपके अभिकलन की संरचना करने के लिए बाध्यकारी संयोजकों के एक पेड़ को जारी रख सकते हैं।

पूर्ण, असूचीबद्ध स्टेट मोनड की व्याख्या के लिए और जावास्क्रिप्ट में सामान्य रूप से मोनाड्स के लिए एक उत्कृष्ट परिचय, इस ब्लॉग पोस्ट को देखें


1
ठीक है, मैं उस पर गौर करूंगा (और बाद में उस पर टिप्पणी करूंगा)। लेकिन आप पैटर्न का उपयोग करने के विचार के बारे में क्या सोचते हैं?
डैनियल कपलान

1
@tieTYT मुझे लगता है कि पैटर्न ही एक बहुत अच्छा विचार है; सामान्य तौर पर स्टेट मोनड छद्म-परिवर्तनशील एल्गोरिदम (एल्गोरिदम जो अपरिवर्तनीय हैं, लेकिन परिवर्तनशीलता का अनुकरण करते हैं) के लिए एक उपयोगी कोड-संरचना उपकरण है।
पथरियन की लौ

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

6
सामान्य रूप से @ लियान मोनड्स का वास्तव में उत्परिवर्तन या ग्लोबल्स से कोई लेना-देना नहीं है; केवल स्टेट मोनाड विशेष रूप से करता है (क्योंकि यह विशेष रूप से ऐसा करने के लिए डिज़ाइन किया गया है)। मैं इस बात से भी असहमत हूं कि राज्य का मुनडा भाषा में परिवर्तनशीलता के साथ उपयोगी नहीं है, हालांकि नीचे दिए गए परिवर्तनशीलता पर निर्भर एक कार्यान्वयन मेरे द्वारा दिए गए अपरिवर्तनीय से अधिक कुशल हो सकता है (हालांकि मैं उसके बारे में निश्चित नहीं हूं)। मोनैडिक इंटरफ़ेस उच्च-स्तरीय क्षमताएं प्रदान कर सकता है जो अन्यथा आसानी से सुलभ नहीं हैं, stateBindमैंने जो कॉम्बिनेटर दिया है , वह इसका एक बहुत ही सरल उदाहरण है।
पीथरीन की लौ

1
@ लाइरियन I दूसरे पंथरीन की टिप्पणी - अधिकांश मठ राज्य या उत्परिवर्तन के बारे में नहीं हैं, और यहां तक ​​कि जो भी है वह विशेष रूप से वैश्विक स्थिति के बारे में नहीं है । मोनाड्स वास्तव में OO / अनिवार्य / उत्परिवर्ती भाषाओं में काफी अच्छी तरह से काम करते हैं।

11

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

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

हिक्की: मैं OO के बारे में बहस करूंगा और पुन: उपयोग करूंगा, लेकिन निश्चित रूप से, चीजों का पुन: उपयोग करने में सक्षम होने से समस्या को सरल बनाया जा सकता है, क्योंकि आप कारों के निर्माण के बजाय पहियों को फिर से नहीं बना रहे हैं। और जेवीएम पर होने वाले क्लोजर बहुत सारे पहियों-पुस्तकालयों को उपलब्ध कराता है। क्या एक पुस्तकालय पुन: प्रयोज्य बनाता है? यह एक या कुछ चीजों को अच्छी तरह से करना चाहिए, अपेक्षाकृत आत्मनिर्भर होना चाहिए, और ग्राहक कोड पर कुछ मांग करना चाहिए। इनमें से कोई भी OO से बाहर नहीं है, और सभी Java लाइब्रेरी इस मानदंड को पूरा नहीं करते हैं, लेकिन कई करते हैं।

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

यह साहचर्य मॉडल है, लेकिन क्लोजर के साथ आपूर्ति किए गए कई अमूर्त तत्वों में से एक है, और ये पुन: उपयोग करने के लिए इसके दृष्टिकोण के सच्चे आधार हैं: सार पर कार्य। एक खुले और बड़े, कार्यों का सेट एक खुले और छोटे पर संचालित होता है, एक्सटेंसिबल एब्स्ट्रक्शन का सेट एल्गोरिथम पुन: उपयोग और लाइब्रेरी इंटरऑपरेबिलिटी की कुंजी है। इन अमूर्तताओं के संदर्भ में क्लोज़र कार्यों के विशाल बहुमत को परिभाषित किया गया है, और पुस्तकालय लेखकों ने उनके इनपुट और आउटपुट स्वरूपों को उनके संदर्भ में डिजाइन किया है, साथ ही साथ स्वतंत्र रूप से विकसित पुस्तकालयों के बीच जबरदस्त अंतर-क्षमता को साकार किया है। यह DOM और अन्य ऐसी चीजों के विपरीत है जो आप OO में देखते हैं। बेशक, आप OO में इसी तरह के एब्स्ट्रैक्ट को इंटरफेस के साथ कर सकते हैं, उदाहरण के लिए, java.util कलेक्शन, लेकिन आप आसानी से java.io की तरह आसानी से नहीं कर सकते।

फोगस ने अपनी पुस्तक कार्यात्मक जावास्क्रिप्ट में इन बिंदुओं को दोहराया :

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

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

यद्यपि डेटा मैप्स के रूप में जावास्क्रिप्ट ऑब्जेक्ट्स में हेरफेर करने और एक्सेस करने के उपकरण जावास्क्रिप्ट के भीतर ही विरल हैं, शुक्र है कि अंडरस्कोर उपयोगी ओपेरा टाइन्स की एक बीवी प्रदान करता है। काबू करने के लिए सबसे सरल कार्यों में से __keys, _.values, और _.pluck हैं। _.Keys और _.values ​​दोनों को उनकी कार्यक्षमता के अनुसार नाम दिया गया है, जो किसी वस्तु को लेना है और उसके किसी अक्षर या मान को लौटाना है ...


2
मैंने इस फोगस / हिक्की साक्षात्कार को पहले पढ़ा था, लेकिन मैं यह समझने में सक्षम नहीं था कि वह अब तक क्या बात कर रहा था। आपके उत्तर के लिए धन्यवाद। अभी भी यकीन नहीं है कि अगर हिक्की / फोगस मेरे डिजाइन को अपना आशीर्वाद देगा। मैं चिंतित हूं कि मैंने उनकी सलाह की भावना को चरम पर पहुंचाया।
डैनियल कपलान

9

शैतान का वकील

मुझे लगता है कि यह सवाल एक शैतान के वकील के योग्य है (लेकिन निश्चित रूप से मैं पक्षपाती हूं)। मुझे लगता है कि @KarlBielefeldt बहुत अच्छे अंक बना रहा है और मैं उन्हें संबोधित करना चाहूंगा। पहले मैं कहना चाहता हूं कि उनके अंक बहुत अच्छे हैं।

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

उदाहरण के लिए, प्रत्येक उपप्रकार फ़ंक्शन के बारे में निम्नलिखित प्रश्नों के उत्तर देने का प्रयास करें:

  • राज्य के किन क्षेत्रों में इसकी आवश्यकता है?

  • यह किन क्षेत्रों को संशोधित करता है?

  • कौन से क्षेत्र अपरिवर्तित हैं?

एक गतिशील रूप से टाइप की गई भाषा में, आप आमतौर पर इन सवालों के जवाब कैसे देंगे? एक फ़ंक्शन का पहला पैरामीटर नाम हो सकता है foo, लेकिन वह क्या है? एक सरणी? एक वस्तु? वस्तुओं के सरणियों का एक उद्देश्य? आपको कैसे पता चलेगा? मुझे पता है कि एक ही रास्ता है

  1. प्रलेखन पढ़ें
  2. फ़ंक्शन बॉडी को देखें
  3. परीक्षणों को देखो
  4. यह देखने के लिए कि क्या काम करता है, प्रोग्राम को देखें और चलाएं।

मुझे नहीं लगता कि "सब कुछ एक नक्शा है" पैटर्न से यहां कोई फर्क पड़ता है। इन सवालों के जवाब देने के बारे में मुझे अभी भी यही एकमात्र तरीका है।

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

मैं "सब कुछ एक नक्शा है" और खराब डिज़ाइन किए गए OO कोड के बीच एक गलत द्वंद्व स्थापित करने की कोशिश नहीं कर रहा हूँ । मैं केवल यह इंगित करने की कोशिश कर रहा हूं कि ऐसे हस्ताक्षर होना जो कम / अधिक बारीक / मोटे दाने वाले मापदंडों में लेते हैं, आपको गारंटी नहीं है कि आप किसी फ़ंक्शन को अलग करना, सेटअप करना और कॉल करना जानते हैं।

लेकिन, अगर आप मुझे उस झूठे द्वंद्ववाद का उपयोग करने की अनुमति देंगे: पारंपरिक ओओपी तरीके से जावास्क्रिप्ट लिखने की तुलना में, "सब कुछ एक नक्शा है" बेहतर लगता है। पारंपरिक ओओपी तरीके से, फ़ंक्शन को उस राज्य को संशोधित या अनदेखा करना पड़ सकता है जिसे आप पास करते हैं या जिस राज्य में आप पास नहीं होते हैं। इस "सब कुछ एक नक्शा है" पैटर्न के साथ, आपको केवल उस राज्य को संशोधित या अनदेखा करना होगा जिसे आप पास करते हैं। में।

  • क्या आप कार्यों के क्रम को सुरक्षित रूप से पुनर्व्यवस्थित कर सकते हैं?

मेरे कोड में, हाँ। @ एवीकाटोस के उत्तर के लिए मेरी दूसरी टिप्पणी देखें। शायद यह केवल इसलिए है क्योंकि मैं एक खेल बना रहा हूं, फिर भी मैं नहीं कह सकता। 60x सेकंड में अपडेट होने वाले गेम में, यह वास्तव में dead guys drop lootतब नहीं होता है जब good guys pick up lootइसके विपरीत या इसके विपरीत। प्रत्येक फ़ंक्शन अभी भी वही करता है जो उसके द्वारा चलाए जाने वाले आदेश की परवाह किए बिना करना चाहिए। updateयदि आप ऑर्डर स्वैप करते हैं तो एक ही डेटा केवल एक अलग कॉल पर उन्हें खिलाया जाता है । यदि आपके पास good guys pick up lootतो dead guys drop lootअच्छे लोगों को अगले में लूट लेने जाएगा updateऔर यह कोई बड़ी बात नहीं है। एक मानव अंतर को नोटिस करने में सक्षम नहीं होगा।

कम से कम यह मेरा सामान्य अनुभव रहा है। मैं इस बात को सार्वजनिक रूप से स्वीकार करने में वास्तव में असुरक्षित महसूस करता हूं। हो सकता है कि यह ठीक हो जाएगा पर विचार एक है बहुत , बहुत बुरी बात नहीं है। मुझे बताएं कि क्या मैंने यहां कुछ भयानक गलती की है। लेकिन, अगर मेरे पास है, तो फ़ंक्शंस को पुनर्व्यवस्थित करना बेहद आसान है इसलिए ऑर्डर dead guys drop lootफिर good guys pick up lootसे है। इस पैराग्राफ को लिखने में जितना समय लगेगा उससे कम समय लगेगा: पी

शायद आपको लगता है कि "मृत लोगों को पहले लूट छोड़ना चाहिए । यह बेहतर होगा यदि आपका कोड उस आदेश को लागू करता है"। लेकिन, इससे पहले कि आप लूट उठा सकें, दुश्मनों को लूट क्यों छोड़नी चाहिए? मेरे लिए यह समझ में नहीं आता है। हो सकता है कि लूट को 100 साल updatesपहले गिराया गया हो। यह जांचने के लिए आवश्यक नहीं है कि एक मनमाना बुरा आदमी को लूट लेना है जो पहले से ही जमीन पर है। इसलिए मुझे लगता है कि इन ऑपरेशनों का क्रम पूरी तरह से मनमाना है।

इस पैटर्न के साथ डिकूप्ड स्टेप्स लिखना स्वाभाविक है, लेकिन पारंपरिक ओओपी में आपके युग्मित चरणों को नोटिस करना मुश्किल है। अगर मैं पारंपरिक OOP लिख रहा था, तो सोचने का स्वाभाविक, भोला तरीका यह है कि dead guys drop lootवापसी को एक ऐसी Lootवस्तु बना दिया जाए जिसमें मुझे गुजरना पड़े good guys pick up loot। मैं उन कार्रवाइयों को फिर से नहीं कर पाऊंगा क्योंकि पहली बार दूसरे का इनपुट लौटाता है।

ऑब्जेक्ट ओरिएंटेड भाषा में, पैटर्न और भी कम समझ में आता है, क्योंकि ट्रैकिंग स्टेट यह है कि ऑब्जेक्ट क्या करते हैं।

ऑब्जेक्ट्स में स्थिति होती है और यह राज्य को अपने इतिहास को गायब करने के लिए उत्परिवर्तित करने के लिए मुहावरेदार होता है ... जब तक कि आप इसे ट्रैक रखने के लिए मैन्युअल रूप से कोड नहीं लिखते हैं। ट्रैकिंग राज्य किस तरीके से "वे क्या करते हैं"?

इसके अलावा, अपरिवर्तनीयता के लाभ आपके अपरिवर्तनीय वस्तुओं को प्राप्त करने के तरीके से नीचे जाते हैं।

जैसा कि मैंने कहा, "यह दुर्लभ है कि मेरा कोई भी कार्य शुद्ध है।" वे हमेशा अपने मापदंडों पर काम करते हैं, लेकिन वे अपने मापदंडों को बदल देते हैं। यह एक समझौता है जिसे मैंने महसूस किया कि मुझे इस पैटर्न को जावास्क्रिप्ट पर लागू करते समय बनाना था।


4
"एक फ़ंक्शन के पहले पैरामीटर को फू नाम दिया जा सकता है, लेकिन वह क्या है?" इसीलिए आप अपने मापदंडों का नाम "फू" नहीं रखते, लेकिन "दोहराव", "माता-पिता", और अन्य नाम जो यह स्पष्ट करते हैं कि फ़ंक्शन नाम के साथ संयुक्त होने पर क्या अपेक्षित है।
सेबस्टियन रेडल

1
मुझे आपके साथ सभी बिंदुओं पर सहमत होना है। एकमात्र समस्या जावास्क्रिप्ट इस पैटर्न के साथ बनती है, यह है कि आप उत्परिवर्तित डेटा पर काम कर रहे हैं, और इस तरह, आप राज्य को म्यूट करने की बहुत संभावना रखते हैं। हालांकि, एक पुस्तकालय है जो आपको सादे जावास्क्रिप्ट में क्लोजर डेटास्ट्रक्चर तक पहुंच प्रदान करता है, बिल्कुल मैं भूल जाता हूं कि इसे क्या कहा जाता है। एक वस्तु के रूप में तर्क पारित करना या तो अनसुना नहीं है, jquery यह कई स्थानों पर करता है, लेकिन दस्तावेजों का उपयोग करता है कि वे किस हिस्से का उपयोग करते हैं। व्यक्तिगत रूप से, हालांकि, मैं UI- फ़ील्ड्स और GameLogic- फ़ील्ड्स को अलग कर दूंगा, लेकिन जो भी आपके लिए काम करता है :)
रोबिन हेगेलुंड हेन्सन

@SebastianRedl मुझे क्या करना चाहिए parent? है repetitionsऔर जो नंबर या तार के सरणी या यह कोई फर्क नहीं पड़ता? या हो सकता है कि repetitions मैं चाहता हूँ कि repretitions की संख्या का प्रतिनिधित्व करने के लिए सिर्फ एक संख्या है? वहाँ बहुत सारे एपिस हैं जो बस एक विकल्प वस्तु लेते हैं । यदि आप चीजों को सही तरीके से नाम देते हैं, तो दुनिया एक बेहतर जगह है, लेकिन यह गारंटी नहीं देता है कि आपको पता चल जाएगा कि एपीआई का उपयोग कैसे करना है, कोई सवाल नहीं पूछा गया।
डैनियल कपलान

8

मैंने पाया है कि मेरा कोड इस तरह संरचित को समाप्त करता है:

  • नक्शे लेने वाले कार्य बड़े होते हैं और दुष्प्रभाव होते हैं।
  • तर्क लेने वाले कार्य छोटे होते हैं और शुद्ध होते हैं।

मैंने इस भेद को बनाने के लिए कोई कसर नहीं छोड़ी है, लेकिन अक्सर ऐसा होता है कि यह मेरे कोड में कैसे समाप्त होता है। मुझे नहीं लगता कि एक शैली का उपयोग जरूरी दूसरे को नकारता है।

शुद्ध कार्य इकाई परीक्षण के लिए आसान हैं। नक्शे के साथ बड़े लोग "एकीकरण" परीक्षण क्षेत्र में अधिक हो जाते हैं क्योंकि वे अधिक चलती भागों को शामिल करते हैं।

जावास्क्रिप्ट में, एक चीज जो बहुत मदद करती है वह पैरामीटर सत्यापन करने के लिए उल्का के मिलान पुस्तकालय जैसी किसी चीज का उपयोग कर रही है। यह बहुत स्पष्ट करता है कि फ़ंक्शन क्या अपेक्षा करता है और नक्शे को काफी सफाई से संभाल सकता है।

उदाहरण के लिए,

function foo (post) {
  check(post, {
    text: String,
    timestamp: Date,
    // Optional, but if present must be an array of strings
    tags: Match.Optional([String])
    });

  // do stuff
}

अधिक के लिए http://docs.meteor.com/#match देखें ।

:: अपडेट करें ::

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


1
मुझे लगता है कि @Evicatos पर मेरी टिप्पणी यहाँ मेरी स्थिति पर विस्तृत होगी। हां, मैं म्यूट कर रहा हूं और फ़ंक्शन शुद्ध नहीं हैं। लेकिन, मेरे कार्यों का परीक्षण करना वास्तव में आसान है, विशेष रूप से प्रतिगमन दोषों के लिए मैं परीक्षण पर योजना नहीं बना रहा था। आधा क्रेडिट जेएस को जाता है: "मैप" / ऑब्जेक्ट का निर्माण करना बहुत आसान है, केवल मेरे परीक्षण के लिए आवश्यक डेटा। तब यह इसे पारित करने और म्यूटेशन की जांच करने जितना आसान है। साइड-इफेक्ट्स को हमेशा मैप में दर्शाया जाता है, इसलिए उन्हें टेस्ट करना आसान होता है।
डैनियल कापलान

1
मेरा मानना ​​है कि दोनों तरीकों का व्यावहारिक उपयोग जाने का "सही" तरीका है। यदि परीक्षण आपके लिए आसान है और आप आवश्यक फ़ील्ड को अन्य डेवलपर्स से संवाद करने की मेटा समस्या को कम कर सकते हैं, तो यह एक जीत की तरह लगता है। आपके सवाल के लिए धन्यवाद; मैंने आपके द्वारा शुरू की गई दिलचस्प चर्चा को पढ़ने का आनंद लिया है।
alanning

5

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

इसका मतलब यह है कि कोडबेस में भविष्य के प्रोग्रामर को यह जानना होगा कि फ़ंक्शन को आंतरिक रूप से कैसे काम किया जा रहा है - और किसी भी नेस्टेड फ़ंक्शन कॉल - इसे कॉल करने के लिए।

जितना अधिक मैं इसके बारे में सोचता हूं, उतनी ही आपकी गेमस्टैट वस्तु एक वैश्विक की तरह बदबू आती है। यदि ऐसा है कि इसका उपयोग कैसे किया जा रहा है, तो इसे क्यों पास करें?


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

1
BTW: re: इसके खिलाफ मुख्य तर्क: यह सच है कि क्या यह क्लोजर या जावास्क्रिप्ट में थे। लेकिन यह एक मूल्यवान बिंदु है। शायद सूचीबद्ध लाभ अब तक की नकारात्मक को पछाड़ देते हैं।
डैनियल कपलान

2
अब मुझे पता है कि मैं इसे एक वैश्विक चर होने के बावजूद इसे पास करने में क्यों परेशान करता हूं: यह मुझे शुद्ध कार्यों को लिखने की अनुमति देता है। अगर मैं अपने gameState = f(gameState)को बदलूं f(), तो परीक्षण करना बहुत मुश्किल है ff()हर बार जब मैं इसे कॉल करता हूं तो एक अलग चीज वापस कर सकता है। लेकिन f(gameState)जब एक ही इनपुट दिया जाता है तो हर बार एक ही चीज़ को वापस करना आसान होता है।
डैनियल कपलान

3

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

update(gameState)
  ...
  gameState = handleUnitCollision(gameState)
  ...
  gameState = handleLoot(gameState)
  ...

तथा

{
  ...
  handleUnitCollision: function() {
    ...
  },
  ...
  handleLoot: function() {
    ...
  },
  ...
  update: function() {
    ...
    this.handleUnitCollision()
    ...
    this.handleLoot()
    ...
  },
  ...
};

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


संबंधित, अधिक सामान्य प्रश्न [ प्रोग्रामर.स्टैकएक्सचेंज.
com

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

@tieTYT आप ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग नहीं कर रहे हैं, इसलिए यह ठीक है
user7610

आप उस निष्कर्ष पर कैसे आए ("यह ठीक है" एक)?
डैनियल कपलान

OO में ईश्वर वस्तु के साथ समस्या यह है कि "वस्तु हर चीज के बारे में इतनी सजग हो जाती है या सभी वस्तुएं ईश्वर वस्तु से इतनी अधिक निर्भर हो जाती हैं कि जब कोई परिवर्तन या ठीक करने के लिए बग होता है, तो इसे लागू करना एक वास्तविक दुःस्वप्न बन जाता है।" source आपके कोड में भगवान ऑब्जेक्ट के बगल में अन्य ऑब्जेक्ट हैं, इसलिए दूसरा भाग कोई समस्या नहीं है। पहले भाग के बारे में, अपने भगवान वस्तु है कार्यक्रम और अपने कार्यक्रम के लिए सब कुछ के बारे में पता होना चाहिए। तो वह भी ठीक है।
user7610

2

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

{ :face :queen :suit :hearts }

मैं सिर्फ दो कीवर्ड तत्वों की सूची या वैक्टर बना सकता हूं। मुझे नहीं पता कि क्या इससे मेमोरी / परफॉर्मेंस पर फर्क पड़ता है इसलिए मैं अभी के लिए मैप्स के साथ जा रहा हूं।

यदि मैं बाद में अपना विचार बदल देता हूं, तो मैंने फैसला किया कि मेरे कार्यक्रम के अधिकांश हिस्सों को एक कार्ड के टुकड़ों तक पहुंचने के लिए "इंटरफ़ेस" के माध्यम से जाना चाहिए, ताकि कार्यान्वयन विवरण नियंत्रित और छिपा हो। मुझे फ़ंक्शंस मिले हैं

(defn face [card] (card :face))
(defn suit [card] (card :suit))

कार्यक्रम के बाकी का उपयोग करता है। कार्ड नक्शे के रूप में कार्यों के लिए पास हो जाते हैं, लेकिन नक्शे का उपयोग करने के लिए फ़ंक्शंस एक सहमत-ऑन इंटरफ़ेस का उपयोग करते हैं और इस तरह गड़बड़ी करने में सक्षम नहीं होना चाहिए।

मेरे कार्यक्रम में, एक कार्ड शायद केवल 2-मूल्यवान मानचित्र होगा। प्रश्न में, पूरे खेल राज्य को मानचित्र के रूप में पास किया जाता है। खेल राज्य एक एकल कार्ड की तुलना में बहुत अधिक जटिल होगा, लेकिन मुझे नहीं लगता कि नक्शे का उपयोग करने के बारे में उठाने के लिए गलती है। एक वस्तु-अपरिहार्य भाषा में मैं बस एक ही बड़ी GameState वस्तु रख सकता था और उसके तरीकों को बुला सकता था, और एक ही समस्या हो सकती है:

class State
  def complex-process()
    state = clone(this) ; or just use 'this' below if mutation is fine
    state.subprocess-one()
    state.subprocess-two()
    state.subprocess-three()
    return state

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


2

मैंने क्या (थोड़ा) से देखा है, किसी एक वैश्विक अपरिवर्तनीय राज्य वस्तु को बनाने के लिए नक्शे या अन्य नेस्टेड संरचनाओं का उपयोग करना, जैसे कि कार्यात्मक भाषाओं में यह काफी सामान्य है, कम से कम शुद्ध वाले, विशेष रूप से स्टेट मोनाड का उपयोग करते समय मोनड @ Ptharien'sFlame के करते हैं सलाह देना

इसे प्रभावी ढंग से उपयोग करने में दो बाधाएँ जो मैंने देखी हैं / जिनके बारे में पढ़ा है (और अन्य उत्तरों का उल्लेख यहां किया गया है) हैं:

  • (अपरिवर्तनीय) अवस्था में एक (गहराई से) नेस्टेड मान को म्यूट करना
  • राज्य के अधिकांश कार्यों को छुपाना, जिन्हें इसकी आवश्यकता नहीं है और बस उन्हें थोड़ा सा देना है जिस पर उन्हें काम करने की आवश्यकता है / म्यूट करें

विभिन्न तकनीकों / सामान्य पैटर्न के एक जोड़े हैं जो इन मुद्दों को कम करने में मदद कर सकते हैं:

पहला Zippers है : ये एक अपरिवर्तित नेस्टेड पदानुक्रम के भीतर गहरी स्थिति को बदल देते हैं।

एक और लेंस है : ये आपको एक विशिष्ट स्थान पर संरचना में ध्यान केंद्रित करते हैं और वहां मूल्य को पढ़ते हैं / बदलते हैं। आप अलग-अलग चीजों पर ध्यान केंद्रित करने के लिए विभिन्न लेंसों को एक साथ जोड़ सकते हैं, OOP में एक समायोज्य संपत्ति श्रृंखला की तरह (जहां आप वास्तविक संपत्ति नामों के लिए चर स्थानापन्न कर सकते हैं!)।

प्रिज़मैटिक ने हाल ही में इस तरह की तकनीक का उपयोग करते हुए, जावास्क्रिप्ट / क्लोजुरस्क्रिप्ट में अन्य चीजों के साथ एक ब्लॉग पोस्ट किया, जिसे आपको देखना चाहिए। वे फ़ंक्शन के लिए विंडो स्थिति के लिए कर्सर (जो वे ज़िपर से तुलना करते हैं) का उपयोग करते हैं:

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

IIRC, वे भी उस पोस्ट में जावास्क्रिप्ट में अपरिवर्तनीयता को छूते हैं।


जिस ओपी का उल्लेख किया गया है, वह फ़ंक्शन को उस स्थिति में सीमित करने के लिए अद्यतन का उपयोग करने की भी चर्चा करता है जो फ़ंक्शन राज्य के नक्शे के एक उपप्रकार में अपडेट कर सकता है। मुझे लगता है कि कोई भी इसे अभी तक नहीं लाया है।
user7610

@ user7610 अच्छा पकड़ना, मुझे विश्वास नहीं हो रहा है कि मैं उस एक का उल्लेख करना भूल गया हूं - मुझे वह फ़ंक्शन (और assoc-inएट अल) पसंद है। लगता है कि मैं सिर्फ मस्तिष्क पर हास्केल था। मुझे आश्चर्य है कि क्या किसी ने इसका जावास्क्रिप्ट पोर्ट किया है? लोग शायद इसे ऊपर ले नहीं किया क्योंकि (मेरे जैसे) वे बात करते हैं :) घड़ी नहीं था
पॉल

@ अंपुल एक अर्थ में उनके पास है क्योंकि यह क्लॉजुरस्क्रिप्ट में उपलब्ध है, लेकिन मुझे यकीन नहीं है कि अगर आपके दिमाग में "मायने रखता है"। यह प्योरस्क्रिप्ट में मौजूद हो सकता है और मेरा मानना ​​है कि कम से कम एक पुस्तकालय है जो जावास्क्रिप्ट में अपरिवर्तनीय डेटा संरचना प्रदान करता है। मुझे उम्मीद है कि उनमें से कम से कम एक के पास ये हैं, अन्यथा वे उपयोग करने के लिए असुविधाजनक होंगे।
डैनियल कपलान

@tieTYT मैं एक देशी जेएस कार्यान्वयन के बारे में सोच रहा था जब मैंने वह टिप्पणी की थी, लेकिन आप क्लूजुरस्क्रिप्ट / प्योरिस्क्रिप्ट के बारे में एक अच्छी बात करते हैं। मुझे अपरिवर्तनीय जेएस में देखना चाहिए और देखना चाहिए कि वहां क्या है, मैंने इससे पहले w / यह काम नहीं किया है।
पौल

1

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

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

यदि आप वास्तव में स्पष्ट रूप से राज्य की प्रतियां बना रहे हैं, इसे संशोधित कर रहे हैं, और फिर उस संशोधित प्रति को वापस कर रहे हैं, तो आगे बढ़ें। मुझे यकीन नहीं है कि आप जावास्क्रिप्ट में क्या करने की कोशिश कर रहे हैं, यह पूरा करने का सबसे अच्छा तरीका है, लेकिन यह शायद "क्लोज़िश" है जो कि क्लजुर उदाहरण है।


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

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

1
आप मुझे एक उदाहरण दिखाने जा रहे हैं क्योंकि इसके साथ मेरे अनुभव में, मैं अपनी इच्छा के अनुसार चीजों को स्थानांतरित कर सकता हूं और इसका बहुत कम प्रभाव पड़ता है। बस इसे अपने आप को साबित करने के लिए, मैंने अपने update()फ़ंक्शन के बीच में दो यादृच्छिक सबप्रोसेस कॉल किए । मैं एक को ऊपर और एक को नीचे की ओर ले गया। मेरे सभी परीक्षण अभी भी पास हुए और जब मैंने अपना खेल खेला तो मुझे कोई बुरा प्रभाव नहीं पड़ा। मुझे लगता है कि मेरे कार्य ठीक क्लोजर उदाहरण के रूप में हैं। हम दोनों हर कदम के बाद अपने पुराने डेटा को फेंक रहे हैं।
डैनियल कपलान

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

1
@ ईवीकाटोस - शुद्ध होने और एक ही हस्ताक्षर होने का मतलब यह नहीं है कि कार्यों का क्रम मायने नहीं रखता है। निर्धारित मूल्य और प्रतिशत लागू छूट के साथ एक मूल्य की गणना करने की कल्पना करें। (-> 10 (- 5) (/ 2))2.5 देता है। (-> 10 (/ 2) (- 5))रिटर्न 0.
ज़क

1

यदि आपके पास एक वैश्विक राज्य ऑब्जेक्ट है, जिसे कभी-कभी "गॉड ऑब्जेक्ट" कहा जाता है, जिसे प्रत्येक प्रक्रिया में पास किया जाता है, तो आप कई कारकों को भ्रमित करते हैं, जिनमें से सभी सामंजस्य को बढ़ाते हैं। ये सभी कारक दीर्घकालिक स्थिरता को नकारात्मक तरीके से प्रभावित करते हैं।

ट्रम्प युग्मन यह विभिन्न तरीकों से डेटा पारित करने से उत्पन्न होता है जिसकी लगभग सभी डेटा की कोई आवश्यकता नहीं होती है, ताकि इसे उस स्थान पर प्राप्त किया जा सके जो वास्तव में इससे निपट सकते हैं। इस तरह की कपलिंग वैश्विक डेटा का उपयोग करने के समान है, लेकिन इसे अधिक समाहित किया जा सकता है। ट्रम्प युग्मन "पता करने की आवश्यकता" के विपरीत है, जिसका उपयोग प्रभावों को स्थानीयकृत करने और क्षति को रोकने के लिए किया जाता है जो कि कोड का एक गलत टुकड़ा पूरे सिस्टम पर हो सकता है।

डेटा नेविगेशन आपके उदाहरण में प्रत्येक उप-प्रक्रिया को यह जानने की जरूरत है कि वास्तव में उस डेटा को कैसे प्राप्त किया जाए जिसकी उसे आवश्यकता है, और इसे संसाधित करने में सक्षम होने और शायद एक नए वैश्विक राज्य ऑब्जेक्ट का निर्माण करने की आवश्यकता है। यह ट्रम्प युग्मन का तार्किक परिणाम है; डेटम पर काम करने के लिए डेटम के पूरे संदर्भ की आवश्यकता होती है। फिर, गैर-स्थानीय ज्ञान एक बुरी चीज है।

यदि आप @paul द्वारा पोस्ट में वर्णित एक "जिपर", "लेंस", या "कर्सर" में गुजर रहे थे, तो यह एक बात है। आप डेटा को पढ़ने और लिखने को नियंत्रित करने के लिए एक्सेस, और ज़िप आदि की अनुमति देने वाले होंगे।

सिंगल रिस्पॉन्सिबिलिटी वॉयलेशन का दावा है कि "सबप्रोसेस-वन", "सबप्रोसेस-टू" और "सबप्रोसेस-थ्री" में से प्रत्येक में केवल एक ही जिम्मेदारी है, अर्थात् इसमें सही मानों के साथ एक नई वैश्विक राज्य वस्तु का उत्पादन करने के लिए, उदाहरण के लिए, घोर कमी है। यह अंत में सभी बिट्स है, है ना?

यहां मेरा कहना यह है कि आपके खेल के सभी प्रमुख घटकों की सभी जिम्मेदारियां समान हैं क्योंकि आपका खेल प्रतिनिधिमंडल और फैक्टरिंग के उद्देश्य को पराजित करता है।

सिस्टम प्रभाव

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

एक और प्रोग्रामर, या दो, या आठ, को जोड़ने से आपकी प्रणाली लगभग तुरंत टूट जाएगी।

  1. देव वस्तुओं के लिए सीखने की अवस्था समतल है (अर्थात, उनमें सक्षम बनने में बहुत लंबा समय लगता है)। प्रत्येक अतिरिक्त प्रोग्रामर को वह सब कुछ सीखने की ज़रूरत होगी जो आप जानते हैं, और इसे अपने सिर में रखें। आप केवल उन प्रोग्रामर को ही काम पर रख पाएंगे जो आपसे बेहतर हैं, यह मानकर कि आप उन्हें भारी ईश्वर की वस्तु बनाए रखने के लिए पर्याप्त कष्ट दे सकते हैं।
  2. आपके विवरण में परीक्षण प्रावधान, केवल सफेद बॉक्स है। आपको परीक्षण के तहत, परीक्षण सेट करने के लिए, इसे चलाने, और यह निर्धारित करने के लिए कि ए ने सही काम किया है, और बी) यह किसी भी काम नहीं किया है, देव वस्तु के हर विवरण के साथ-साथ परीक्षण के तहत मॉड्यूल को जानने की जरूरत है। 10,000 गलत चीजों की। बाधाओं को आपके खिलाफ बहुत ढेर कर दिया जाता है।
  3. एक नई सुविधा को जोड़ने के लिए यह आवश्यक है कि आप) प्रत्येक सबप्रोसेस से गुजरें और यह निर्धारित करें कि क्या फीचर इसमें किसी भी कोड को प्रभावित करता है और इसके विपरीत, b) अपने वैश्विक स्थिति से गुजरता है और परिवर्धन को डिजाइन करता है, और c) प्रत्येक यूनिट टेस्ट से गुजरता है और इसे संशोधित करता है यह जांचने के लिए कि परीक्षण के तहत किसी इकाई ने नई सुविधा को प्रतिकूल रूप से प्रभावित नहीं किया है

आखिरकार

  1. दैवी वस्तुओं को मेरे प्रोग्रामिंग अस्तित्व का अभिशाप बना दिया गया है, कुछ मेरे स्वयं के कर रहे हैं, और कुछ जिन्हें मैं फंस गया हूं।
  2. स्टेट मोनाड स्केल नहीं करता है। राज्य तेजी से बढ़ता है, परीक्षण और संचालन के सभी निहितार्थों के साथ। जिस तरह से हम आधुनिक प्रणालियों में राज्य को नियंत्रित करते हैं वह प्रतिनिधिमंडल (जिम्मेदारियों का विभाजन) और स्कूपिंग (केवल राज्य के एक सबसेट तक पहुंच को प्रतिबंधित करता है) द्वारा होता है। "सब कुछ एक नक्शा है" दृष्टिकोण राज्य को नियंत्रित करने का सटीक विपरीत है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.