मापदंडों के रूप में अन्य कार्यों में पासिंग कार्य, खराब अभ्यास?


40

हम यह बदलने की प्रक्रिया में हैं कि हमारे AS3 एप्लिकेशन हमारी बैक एंड से कैसे बात करते हैं और हम अपने पुराने को बदलने के लिए REST सिस्टम लागू करने की प्रक्रिया में हैं।

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

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


22
आप ऐसा क्यों महसूस करते हैं? क्या आपके पास कार्यात्मक प्रोग्रामिंग के साथ कोई अनुभव है? (मैं नहीं
मानूंगा

8
फिर इसे एक सबक मानें! अकादमिया क्या सिखाती है और वास्तव में क्या उपयोगी है अक्सर आश्चर्यजनक रूप से थोड़ा ओवरलैप होता है। वहाँ प्रोग्रामिंग तकनीकों की एक पूरी दुनिया है कि हठधर्मिता के अनुरूप नहीं है।
फ़ॉसी

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

36
मेरे दिन में वापस हम इन कॉल को फंक्शन्स "कॉलबैक" के माध्यम से बुलाते हैं
माइक

जवाबों:


84

यह एक समस्या नहीं है।

यह एक ज्ञात तकनीक है। ये उच्च क्रम के कार्य हैं (कार्य जो पैरामीटर के रूप में कार्य लेते हैं)।

इस तरह का फ़ंक्शन कार्यात्मक प्रोग्रामिंग में एक बुनियादी बिल्डिंग ब्लॉक भी है और इसका उपयोग हस्केल जैसी कार्यात्मक भाषाओं में बड़े पैमाने पर किया जाता है ।

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


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


8
अगर आप इसका उपयोग कैसे करते हैं, इस पर नियंत्रण चाहते हैं, तो @BlueHat आप निजी होने के लिए कुछ घोषित करते हैं, यदि वह उपयोग विशिष्ट कार्यों के लिए कॉलबैक के रूप में है तो वह ठीक है
शाफ़्ट फ्रीक

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

2
ध्यान देने योग्य बात यह है कि यदि आप अपने आप को रचनाकारों के रूप में कार्यों के साथ ठोस कक्षाएं लिखते हुए पाते हैं तो आप शायद इसे गलत कर रहे हैं
Gusdor

30

वे केवल कार्यात्मक प्रोग्रामिंग के लिए उपयोग नहीं किए जाते हैं। उन्हें कॉलबैक के रूप में भी जाना जा सकता है :

कॉलबैक निष्पादन योग्य कोड का एक टुकड़ा होता है जिसे अन्य कोड के तर्क के रूप में पारित किया जाता है, जिसे कुछ सुविधाजनक समय पर तर्क को वापस करने (निष्पादित करने) की उम्मीद है। आहरण समकालिक कॉलबैक के रूप में तत्काल हो सकता है या बाद के समय में, अतुल्यकालिक कॉलबैक में हो सकता है।

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

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


1
+1 कॉलबैक शब्दावली का उपयोग करने के लिए। मैं इस शब्द को "उच्च आदेश कार्यों" की तुलना में अधिक बार सामना करता हूं।
रॉडने शुलर

मुझे यह उत्तर पसंद है, क्योंकि ओपी को कॉलबैक का वर्णन करना प्रतीत हो रहा था, विशेष रूप से, और सामान्य रूप से उच्चतर ऑर्डर फ़ंक्शन नहीं: "उदाहरण के लिए हमारे क्लास जो हमारे सर्वर को कॉल करता है, एक फ़ंक्शन में लेता है कि वह तब कॉल करेगा और एक ऑब्जेक्ट पास करेगा जब प्रक्रिया पूरी हो गई है और त्रुटियों को नियंत्रित किया गया है आदि "
Ajedi32

11

यह बुरी चीज़ नहीं है। वास्तव में, यह एक बहुत अच्छी बात है।

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

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

तकनीकी रूप से, C ++ फ़ंक्टर भी एक प्रकार का कॉलबैक ऑब्जेक्ट है, जो operator()()समान कार्य करने के लिए, सिंटैक्टिक शुगर का लाभ उठाता है।

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

अन्य लोगों ने कार्यात्मक प्रोग्रामिंग का उल्लेख किया है और उन भाषाओं में कैसे गुजरना बहुत स्वाभाविक है। लैम्ब्डा और कॉलबैक, प्रक्रियात्मक और ओओपी भाषाएं हैं जो कि नकल करती हैं, और वे बहुत शक्तिशाली और उपयोगी हैं।


साथ ही, C # डेलीगेट्स और लैम्ब्डा दोनों का बड़े पैमाने पर उपयोग किया जाता है।
ईविल डॉग पाई

6

जैसा कि पहले ही कहा गया है, यह बुरा अभ्यास नहीं है। यह जिम्मेदारी से अलग करने और अलग करने का एक तरीका है। उदाहरण के लिए, OOP में आप ऐसा कुछ करेंगे:

public void doSomethingGeneric(ISpecifier specifier) {
    //do generic stuff
    specifier.doSomethingSpecific();
    //do some other generic stuff
}

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


1
यह मुहावरा बस, एक अंतरफलक में समारोह लपेटकर है बहुत में एक कच्चे समारोह पारित करने के लिए कुछ इसी तरह पूरा करने।

हाँ यह है, मैं सिर्फ यह दिखाना चाहता था कि यह एक असामान्य अभ्यास नहीं है।
फिलिप मुरी

3

सामान्य तौर पर, अन्य कार्यों को पास करने में कुछ भी गलत नहीं है। यदि आप अतुल्यकालिक कॉल कर रहे हैं और परिणाम के साथ कुछ करना चाहते हैं, तो आपको कुछ प्रकार के कॉलबैक तंत्र की आवश्यकता होगी।

हालांकि साधारण कॉलबैक की कुछ संभावित कमियां हैं:

  • कॉल की एक श्रृंखला बनाने के लिए कॉलबैक की गहरी घोंसले के शिकार की आवश्यकता हो सकती है।
  • त्रुटि हैंडलिंग कॉल के अनुक्रम में प्रत्येक कॉल के लिए पुनरावृत्ति की आवश्यकता हो सकती है।
  • कई कॉल को समन्वित करना अजीब है, जैसे एक ही समय में कई कॉल करना और फिर एक बार कुछ करना।
  • कॉल का एक सेट रद्द करने का कोई सामान्य तरीका नहीं है।

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

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


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